网络流(置顶)

poj1637 判断混合图是否能形成欧拉回路:网络流做奇偶性判断(inspire)

  1 //dinic算法:
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <iostream>
  6 #include <algorithm>
  7 
  8 #define INF 0x3f3f3f3f
  9 using namespace std;
 10 const int maxn = 2010;
 11 const int maxm = 19010;
 12 
 13 int e,S,T;
 14 int first[maxn],next[maxm],work[maxm];
 15 int u[maxm],v[maxm],w[maxm];
 16 
 17 void init(){
 18     e = 0;
 19     memset(first,-1,sizeof(first));
 20 }
 21 
 22 void addedge(int a,int b,int c){
 23     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
 24     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
 25 }
 26 int d[maxn],q[maxn];
 27 int bfs(){
 28     int rear = 0;
 29     memset(d,-1,sizeof(d));
 30     d[S] = 0;q[rear++] = S;
 31     for(int i = 0;i < rear;i++){
 32         for(int j = first[q[i]];j != -1;j = next[j])
 33             if(w[j] && d[v[j]] == -1){
 34                 d[v[j]] = d[q[i]] + 1;
 35                 q[rear++] = v[j];
 36                 if(v[j] == T)   return 1;
 37             }
 38     }
 39     return 0;
 40 }
 41 
 42 int dfs(int cur,int a){
 43     if(cur == T)    return a;
 44     for(int &i = work[cur];i != -1;i = next[i]){
 45         if(w[i] && d[v[i]] == d[cur] + 1)
 46             if(int t = dfs(v[i],min(a,w[i]))){
 47                 w[i] -= t;w[i^1] += t;
 48                 return t;
 49             }
 50     }
 51     return 0;
 52 }
 53 
 54 int dinic(){
 55     int ans = 0;
 56     while(bfs()){
 57         memcpy(work,first,sizeof(first));
 58         while(int t = dfs(S,INF))   ans += t;
 59     }
 60     return ans;
 61 }
 62 int M,N,CASE;
 63 int ind[maxn],outd[maxn];
 64 int main(){
 65     scanf("%d",&CASE);
 66     while(CASE--)
 67     {
 68         scanf("%d%d",&N,&M);
 69         init();
 70         S=N+1;T=N+2;
 71         memset(ind,0,sizeof(ind));
 72         memset(outd,0,sizeof(outd));
 73         for(int i=1;i<=M;i++){
 74             int x,y,c;
 75             scanf("%d%d%d",&x,&y,&c);
 76             if (c==1) outd[x]++,ind[y]++;
 77             if (c!=1) {
 78                 outd[x]++,ind[y]++;
 79                 addedge(x,y,1);
 80             }
 81         }
 82         bool isok=true;
 83         for(int i=1;i<=N;i++) if ((outd[i]-ind[i])%2!=0) isok=false;
 84         if (!isok) {
 85             printf("impossible\n");
 86             continue;
 87         }
 88         int sum=0;
 89         for(int i=1;i<=N;i++){
 90             int k=(outd[i]-ind[i])/2;
 91             if (k<0) addedge(i,T,-k);
 92             if (k>0) {
 93                 sum+=k;
 94                 addedge(S,i,k);
 95             }
 96         }
 97         int flow=dinic();
 98 ////        cout<<sum<<","<<flow<<endl;
 99         if (flow==sum) printf("possible\n");else printf("impossible\n");
100     }
101     return 0;
102 }
View Code

poj3281最大流,巧妙构图

 1 //poj2391
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <math.h>
 5 #include <iostream>
 6 #include <algorithm>
 7 #define LL long long
 8 #define INF 1<<30
 9 #define maxn 510
10 #define maxm 51000
11 using namespace std;
12 
13 
14 int v[maxm],next[maxm],w[maxm];
15 int first[maxn],d[maxn],work[maxn],q[maxn];
16 int e,S,T,n,m;
17 
18 void init(){
19     e = 0;
20     memset(first,-1,sizeof(first));
21 }
22 
23 void addedge(int a,int b,int c){
24     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
25     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
26 }
27 
28 int bfs(){
29     int rear = 0;
30     memset(d,-1,sizeof(d));
31     d[S] = 0;q[rear++] = S;
32     for(int i = 0;i < rear;i++){
33         for(int j = first[q[i]];j != -1;j = next[j])
34             if(w[j] && d[v[j]] == -1){
35                 d[v[j]] = d[q[i]] + 1;
36                 q[rear++] = v[j];
37                 if(v[j] == T)   return 1;
38             }
39     }
40     return 0;
41 }
42 
43 int dfs(int cur,int a){
44     if(cur == T)    return a;
45     for(int &i = work[cur];i != -1;i = next[i]){
46         if(w[i] && d[v[i]] == d[cur] + 1)
47             if(int t = dfs(v[i],min(a,w[i]))){
48                 w[i] -= t;w[i^1] += t;
49                 return t;
50             }
51     }
52     return 0;
53 }
54 
55 int dinic(){
56     int ans = 0;
57     while(bfs()){
58         memcpy(work,first,sizeof(first));
59         while(int t = dfs(S,INF))   ans += t;
60     }
61     return ans;
62 }
63 
64 int F,D,N;
65 int main(){
66     while(~scanf("%d%d%d",&N,&F,&D)){
67         init();
68         S=0;T=2*N+F+D+1;
69         for(int i=1;i<=F;i++) addedge(S,i,1);
70         for(int i=1;i<=D;i++) addedge(F+2*N+i,T,1);
71         for(int i=1;i<=N;i++) addedge(F+i,F+N+i,1);
72         for(int i=1;i<=N;i++){
73             int k1,k2;
74             scanf("%d%d",&k1,&k2);
75             for(int j=1;j<=k1;j++){
76                 int k;scanf("%d",&k);
77                 addedge(k,F+i,1);
78             }
79             
80             
81             for(int j=1;j<=k2;j++){
82                 int k;scanf("%d",&k);
83                 addedge(F+N+i,F+2*N+k,1);
84             }
85         }
86         int flow=dinic();
87         printf("%d\n",flow);
88     }
89     return 0;
90 }
View Code

//注意规范建点建边,注意建图本身

 

woj1124 差分约束系统+最大流

  1 //woj1124
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <vector>
  6 #include <iostream>
  7 #include <algorithm>
  8 #define LL long long
  9 #define INF 1<<30
 10 #define maxn 1310
 11 #define maxm 51000
 12 using namespace std;
 13 
 14 
 15 int v[maxm],next[maxm],w[maxm];
 16 int first[maxn],d[maxn],work[maxn],q[maxn];
 17 int e,S,T,n,m;
 18 
 19 void init(){
 20     e = 0;
 21     memset(first,-1,sizeof(first));
 22 }
 23 
 24 void addedge(int a,int b,int c){
 25     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
 26     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
 27 }
 28 
 29 int bfs(){
 30     int rear = 0;
 31     memset(d,-1,sizeof(d));
 32     d[S] = 0;q[rear++] = S;
 33     for(int i = 0;i < rear;i++){
 34         for(int j = first[q[i]];j != -1;j = next[j])
 35             if(w[j] && d[v[j]] == -1){
 36                 d[v[j]] = d[q[i]] + 1;
 37                 q[rear++] = v[j];
 38                 if(v[j] == T)   return 1;
 39             }
 40     }
 41     return 0;
 42 }
 43 
 44 int dfs(int cur,int a){
 45     if(cur == T)    return a;
 46     for(int &i = work[cur];i != -1;i = next[i]){
 47         if(w[i] && d[v[i]] == d[cur] + 1)
 48             if(int t = dfs(v[i],min(a,w[i]))){
 49                 w[i] -= t;w[i^1] += t;
 50                 return t;
 51             }
 52     }
 53     return 0;
 54 }
 55 
 56 int dinic(){
 57     int ans = 0;
 58     while(bfs()){
 59         memcpy(work,first,sizeof(first));
 60         while(int t = dfs(S,INF))   ans += t;
 61     }
 62     return ans;
 63 }
 64 int N,M;
 65 int score[110];
 66 struct Node{
 67     int u,v;
 68 };
 69 vector<Node>Com;
 70 int main(){
 71     while(~scanf("%d%d",&N,&M)){
 72         Com.clear();
 73         for(int i=1;i<=N;i++) scanf("%d",&score[i]);
 74         for(int i=1;i<=M;i++){
 75             int u,v;
 76             scanf("%d%d",&u,&v);
 77             if (u==N || v==N) score[N]+=2;else Com.push_back((Node){u,v});
 78         }
 79         bool flag=true;
 80         for(int i=1;i<N;i++) {
 81             if (score[i]>=score[N]) flag=false;
 82         }
 83         if (!flag){
 84             printf("NO\n");
 85             continue;
 86         }
 87         S=0;T=1300;
 88         init();
 89         /*队伍:1--N;比赛:N+1--N+COM.SIZE();S;T*/ 
 90         for(int i=1;i<N;i++) addedge(i,T,score[N]-score[i]-1);//差分约束系统 
 91         for(int i=1;i<=Com.size();i++) addedge(S,N+i,2);
 92         for(int i=0;i<Com.size();i++){
 93             int u,v,k;
 94             u=Com[i].u,v=Com[i].v,k=i+1;
 95             addedge(N+k,u,2);
 96             addedge(N+k,v,2);
 97         }
 98         int flow=dinic();
 99     //    cout<<flow<<endl;
100         if (flow==2*Com.size()) printf("YES\n");else printf("NO\n");
101     }
102     return 0;
103 }
View Code

//注意T的设置

sgu326 差分约束系统+最大流

  1 //sgu326
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <math.h>
  5 #include <vector>
  6 #include <iostream>
  7 #include <algorithm>
  8 #define LL long long
  9 #define INF 1<<30
 10 #define maxn 510
 11 #define maxm 91000
 12 using namespace std;
 13 
 14 
 15 int v[maxm],next[maxm],w[maxm];
 16 int first[maxn],d[maxn],work[maxn],q[maxn];
 17 int e,S,T,n,m;
 18 
 19 void init(){
 20     e = 0;
 21     memset(first,-1,sizeof(first));
 22 }
 23 
 24 void addedge(int a,int b,int c){
 25     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
 26     v[e] = a;next[e] = first[b];w[e] = 0;first[b] = e++;
 27 }
 28 
 29 int bfs(){
 30     int rear = 0;
 31     memset(d,-1,sizeof(d));
 32     d[S] = 0;q[rear++] = S;
 33     for(int i = 0;i < rear;i++){
 34         for(int j = first[q[i]];j != -1;j = next[j])
 35             if(w[j] && d[v[j]] == -1){
 36                 d[v[j]] = d[q[i]] + 1;
 37                 q[rear++] = v[j];
 38                 if(v[j] == T)   return 1;
 39             }
 40     }
 41     return 0;
 42 }
 43 
 44 int dfs(int cur,int a){
 45     if(cur == T)    return a;
 46     for(int &i = work[cur];i != -1;i = next[i]){
 47         if(w[i] && d[v[i]] == d[cur] + 1)
 48             if(int t = dfs(v[i],min(a,w[i]))){
 49                 w[i] -= t;w[i^1] += t;
 50                 return t;
 51             }
 52     }
 53     return 0;
 54 }
 55 
 56 int dinic(){
 57     int ans = 0;
 58     while(bfs()){
 59         memcpy(work,first,sizeof(first));
 60         while(int t = dfs(S,INF))   ans += t;
 61     }
 62     return ans;
 63 }
 64 int cnt,u2[410],v2[410],r2[410];
 65 int w2[25];
 66 int N;
 67 int main(){
 68     while(~scanf("%d",&N)){
 69         for(int i=1;i<=N;i++) scanf("%d",&w2[i]);
 70         for(int i=1;i<=N;i++) {
 71             int k;scanf("%d",&k);
 72             if (i==1) w2[1]+=k;
 73         }
 74         cnt=0;
 75         for(int i=1;i<=N;i++){
 76             for(int j=1;j<=N;j++){
 77                 int k;scanf("%d",&k);
 78                 if (i==1 || j==1 || k==0 || i>=j) continue;
 79                 u2[cnt]=i;v2[cnt]=j;r2[cnt++]=k;
 80             }
 81         }
 82         bool isok=true;
 83         for(int i=2;i<=N;i++) if (w2[i]>w2[1]) {
 84             isok=false;break;
 85         }
 86         if (!isok){
 87             printf("NO\n");
 88             continue;
 89         }
 90         int sum=0;
 91         S=0;T=501;
 92         init();
 93         //比赛:N+1--N+cnt,队伍1--N 
 94         for(int i=0;i<cnt;i++){
 95             addedge(S,N+i+1,r2[i]);
 96             sum+=r2[i];
 97         }
 98         for(int i=2;i<=N;i++){
 99             addedge(i,T,w2[1]-w2[i]);
100         }
101         for(int i=0;i<cnt;i++){
102             addedge(N+i+1,u2[i],r2[i]);
103             addedge(N+i+1,v2[i],r2[i]);
104         }
105         int flow=dinic();
106         if (flow==sum) printf("YES\n");else printf("NO\n");
107     }
108     return 0;
109 }
View Code

 

posted @ 2014-05-02 23:28  little_w  阅读(158)  评论(0编辑  收藏  举报