【网络流】网络流小总结
一、dinic最大流
我的模板。模板上已經有了dfs上的優化(比我以前的快多了。。)優化啊優化。
bool bfs(int st,int ed) {while(!q.empty()) q.pop();memset(d,-1,sizeof(d));q.push(st);d[st]=0;while(!q.empty()){int x=q.front();q.pop();for(int i=first[x];i!=-1;i=a[i].next){int y=a[i].y;if(d[y]==-1 && a[i].d>0){d[y]=d[x]+1;q.push(y);}} }return (d[ed]!=-1); }int dfs(int x,int flow,int ed) {int k,p,r=0;if(x==ed) return flow;for(int i=first[x];i!=-1;i=a[i].next){int y=a[i].y;if(d[y]==d[x]+1 && a[i].d>0){p=minn(a[i].d,flow-r);p=dfs(y,p,ed);r+=p; //優化,把從這個點開始能流的全部流了a[i].d-=p;a[i^1].d+=p;}if(r==flow) break; // 優化 }if(!r) d[x]=-1; //優化return r; }int dinic(int st,int ed) {int ans=0;while(bfs(st,ed)){int k;while(k=dfs(st,INF,ed)) ans+=k;}return ans; } dinic?
?
二、上下界網絡流
建立超級源點ss,超級匯點tt(上圖中的s改為ss,t改為tt)
對于每條x到y,下界為k1,上界為k2的邊(x,y,k1,k2),拆成如圖這種形式:(x,y,k2-k1)(自由流),(ss,y,k1)(必須流入),(x,tt,k1)(必須流出)。
(1)沒有源點和匯點:
可行流:跑一遍最大流,看是否滿流。滿流則有可行流。
最大流:每條邊加一個費用f=1,然后跑最大費用循環流(詳見下面)。
最小流:每條邊加一個費用f=1,然后跑最小費用循環流。
(2)有源點和匯點:
原來的源點s,原來的匯點t。在s和t之間建邊(t,s,INF),使原圖變為無源匯的循環流。
可行流:拆邊后跑一遍最大流,滿流則有可行流。
最大流:去掉ss、tt(去掉后無論怎么跑都是已經滿足了下界的可行流),然后從原來的源匯點s到t跑一遍最大流,讓殘余網絡的增廣路全部加上去。此時(s,t,INF)的那條邊的反向邊(t,s)的流量就是答案。
最小路:去掉ss、tt后,從原來的源匯點t到s跑一遍最大流(逆向求解,讓最多的流量還回去)。
上下界網絡路講解:http://www.cnblogs.com/kane0526/archive/2013/04/05/3001108.html
模板(poj2396)
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 9 const int N=500,M=500,INF=(int)1e9; 10 const int S=N+M+4; 11 int n,m,s,t,ss,tt,len,sum,bk; 12 int d[N+M+4],p[N][M],first[N+M+4],map[2][N][M]; 13 struct node{int x,y,d,next;}a[N*M*2]; 14 queue<int> q; 15 16 int minn(int x,int y){return x<y ? x:y;} 17 int maxx(int x,int y){return x>y ? x:y;} 18 19 void ins(int x,int y,int d) 20 { 21 a[++len].x=x;a[len].y=y;a[len].d=d; 22 a[len].next=first[x];first[x]=len; 23 if(x==ss) sum+=d; 24 swap(x,y); 25 a[++len].x=x;a[len].y=y;a[len].d=0; 26 a[len].next=first[x];first[x]=len; 27 } 28 29 void make_edge(int x,int y) 30 { 31 if(map[0][x][y]>map[1][x][y]) bk=0; 32 if(map[0][x][y]==0) ins(x,y,map[1][x][y]); 33 else 34 { 35 ins(ss,y,map[0][x][y]); 36 ins(x,tt,map[0][x][y]); 37 ins(x,y,map[1][x][y]-map[0][x][y]); 38 } 39 } 40 41 void build(char c,int x,int y,int z) 42 { 43 int t1=0,t2=INF; 44 if(c=='=') t1=t2=z; 45 if(c=='>') t1=z+1; 46 if(c=='<') t2=z-1; 47 map[0][x][y]=maxx(map[0][x][y],t1); 48 map[1][x][y]=minn(map[1][x][y],t2); 49 50 } 51 52 bool bfs(int st,int ed) 53 { 54 while(!q.empty()) q.pop(); 55 memset(d,-1,sizeof(d)); 56 q.push(st); 57 d[st]=0; 58 while(!q.empty()) 59 { 60 int x=q.front();q.pop(); 61 for(int i=first[x];i!=-1;i=a[i].next) 62 { 63 int y=a[i].y; 64 if(d[y]==-1 && a[i].d>0) 65 { 66 d[y]=d[x]+1; 67 q.push(y); 68 } 69 } 70 } 71 return (d[ed]!=-1); 72 } 73 74 int dfs(int x,int flow,int ed) 75 { 76 int k,p,r=0; 77 if(x==ed) return flow; 78 for(int i=first[x];i!=-1;i=a[i].next) 79 { 80 int y=a[i].y; 81 if(d[y]==d[x]+1 && a[i].d>0) 82 { 83 p=minn(a[i].d,flow-r); 84 p=dfs(y,p,ed); 85 r+=p; 86 a[i].d-=p; 87 a[i^1].d+=p; 88 } 89 } 90 if(!r) d[x]=-1; 91 return r; 92 } 93 94 int dinic(int st,int ed) 95 { 96 int ans=0; 97 while(bfs(st,ed)) 98 { 99 int k; 100 while(k=dfs(st,INF,ed)) ans+=k; 101 } 102 return ans; 103 } 104 105 int main() 106 { 107 freopen("a.in","r",stdin); 108 freopen("a.out","w",stdout); 109 int T; 110 scanf("%d",&T); 111 while(T--) 112 { 113 scanf("%d%d",&n,&m); 114 int x,y,z,k; 115 char c; 116 s=n+m+1;t=s+1;ss=t+1;tt=ss+1; 117 len=-1;sum=0;bk=1; 118 memset(first,-1,sizeof(first)); 119 memset(map[0],0,sizeof(map[0])); 120 memset(map[1],63,sizeof(map[1])); 121 memset(p,0,sizeof(p)); 122 int sum1=0,sum2=0; 123 for(int i=1;i<=n;i++) 124 { 125 scanf("%d",&x); 126 map[0][s][i]=map[1][s][i]=x; 127 make_edge(s,i); 128 sum1+=x; 129 } 130 for(int i=n+1;i<=n+m;i++) 131 { 132 scanf("%d",&x); 133 map[0][i][t]=map[1][i][t]=x; 134 make_edge(i,t); 135 sum2+=x; 136 } 137 if(sum1!=sum2) bk=0; 138 scanf("%d",&k); 139 for(int i=1;i<=k;i++) 140 { 141 scanf("%d%d",&x,&y);getchar(); 142 scanf("%c%d",&c,&z); 143 if(x && y) build(c,x,y+n,z); 144 if(!x && y) 145 for(int j=1;j<=n;j++) 146 build(c,j,y+n,z); 147 if(x && !y) 148 for(int j=1;j<=m;j++) 149 build(c,x,j+n,z); 150 if(!x && !y) 151 for(int j=1;j<=n;j++) 152 for(int l=1;l<=m;l++) 153 build(c,j,l+n,z); 154 } 155 for(int i=1;i<=n;i++) 156 for(int j=n+1;j<=n+m;j++) 157 make_edge(i,j); 158 ins(t,s,INF); 159 if(!bk || dinic(ss,tt)!=sum) printf("IMPOSSIBLE\n"); 160 else 161 { 162 for(int i=0;i<len;i++) 163 { 164 x=a[i].x;y=a[i].y; 165 if(x<=n+m && y<=n+m) 166 { 167 if(!p[x][y-n]) p[x][y-n]=map[0][x][y]+a[i^1].d; 168 } 169 } 170 for(int i=1;i<=n;i++) 171 { 172 for(int j=1;j<=m;j++) 173 printf("%d ",p[i][j]); 174 printf("\n"); 175 } 176 } 177 printf("\n"); 178 } 179 return 0; 180 } poj2396?
三、最小費用最大流
在滿足最大流的前提下求最小費用,就是在bfs的時候找一條費用最小的增廣路。
1 void ins(int x,int y,int d,int f) 2 { 3 a[++len].x=x;a[len].y=y;a[len].d=d;a[len].f=f; 4 a[len].next=first[x];first[x]=len; 5 a[++len].x=y;a[len].y=x;a[len].d=0;a[len].f=-f; 6 a[len].next=first[y];first[y]=len; 7 } 8 9 int bfs(int st,int ed) 10 { 11 while(!q.empty()) q.pop(); 12 memset(pre,-1,sizeof(pre)); 13 memset(dis,63,sizeof(dis)); 14 memset(in,0,sizeof(in)); 15 memset(flow,0,sizeof(flow)); 16 pre[st]=0;dis[st]=0;in[st]=1;flow[st]=INF;q.push(st); 17 while(!q.empty()) 18 { 19 int x=q.front();in[x]=0;q.pop(); 20 for(int i=first[x];i!=-1;i=a[i].next) 21 { 22 int y=a[i].y; 23 if(a[i].d && dis[y]>dis[x]+a[i].f) 24 { 25 dis[y]=dis[x]+a[i].f; 26 pre[y]=i; 27 flow[y]=minn(a[i].d,flow[x]); 28 if(!in[y]) {in[y]=1;q.push(y);} 29 } 30 } 31 } 32 if(pre[ed]==-1) return -1; 33 return flow[ed]; 34 } 35 36 void MFMC(int st,int ed)//max flow min cost 37 { 38 int k,p; 39 fl=0,cl=0; 40 while((k=bfs(st,ed))!=-1) 41 { 42 fl+=k; 43 cl+=dis[ed]*k; 44 p=ed; 45 while(p!=st) 46 { 47 a[pre[p]].d-=k; 48 a[pre[p]^1].d+=k; 49 p=a[pre[p]].x; 50 } 51 } 52 } 費用流?
四、最小割
根據最大流最小割原理,最大流就是最小割。主要是建圖模型。
經典例題:一些資源,要不給A,要不給B,有相應的收益,問最大收益。寫在我的題表里了。
我寫了題解:http://www.cnblogs.com/KonjakJuruo/p/5516479.html
?
五、最大費用循環流
每條邊有上下界k1、k2,費用f。問最大費用循環流。
對于每條邊(x,y,k1,k2,f),拆成:
1.(x,y,k1,k1,f) ?(再按上下界拆邊,即(s,y,k1,f) (x,t,k1,f)), (x到y之間一定要流k1的流量)
2.(y,x,k2-k1,-f) ?, ??(s,y,k2-k1,0) ? , ? (x,t,k2-f1,f); ?(x到y之間有k2-k1的自由流,先假設全部都可以得到,然后建(y,x,k2-k1,-f)就是給它反悔的機會,如果必須反悔就減回f*流量)
跑最大流,用k2的和判滿流,滿流則有解。
?
重點來了,題表及代碼:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 9 const int N=500,M=500,INF=(int)1e9; 10 const int S=N+M+4; 11 int n,m,s,t,ss,tt,len,sum,bk; 12 int d[N+M+4],p[N][M],first[N+M+4],map[2][N][M]; 13 struct node{int x,y,d,next;}a[N*M*2]; 14 queue<int> q; 15 16 int minn(int x,int y){return x<y ? x:y;} 17 int maxx(int x,int y){return x>y ? x:y;} 18 19 void ins(int x,int y,int d) 20 { 21 a[++len].x=x;a[len].y=y;a[len].d=d; 22 a[len].next=first[x];first[x]=len; 23 if(x==ss) sum+=d; 24 swap(x,y); 25 a[++len].x=x;a[len].y=y;a[len].d=0; 26 a[len].next=first[x];first[x]=len; 27 } 28 29 void make_edge(int x,int y) 30 { 31 if(map[0][x][y]>map[1][x][y]) bk=0; 32 if(map[0][x][y]==0) ins(x,y,map[1][x][y]); 33 else 34 { 35 ins(ss,y,map[0][x][y]); 36 ins(x,tt,map[0][x][y]); 37 ins(x,y,map[1][x][y]-map[0][x][y]); 38 } 39 } 40 41 void build(char c,int x,int y,int z) 42 { 43 int t1=0,t2=INF; 44 if(c=='=') t1=t2=z; 45 if(c=='>') t1=z+1; 46 if(c=='<') t2=z-1; 47 map[0][x][y]=maxx(map[0][x][y],t1); 48 map[1][x][y]=minn(map[1][x][y],t2); 49 50 } 51 52 bool bfs(int st,int ed) 53 { 54 while(!q.empty()) q.pop(); 55 memset(d,-1,sizeof(d)); 56 q.push(st); 57 d[st]=0; 58 while(!q.empty()) 59 { 60 int x=q.front();q.pop(); 61 for(int i=first[x];i!=-1;i=a[i].next) 62 { 63 int y=a[i].y; 64 if(d[y]==-1 && a[i].d>0) 65 { 66 d[y]=d[x]+1; 67 q.push(y); 68 } 69 } 70 } 71 return (d[ed]!=-1); 72 } 73 74 int dfs(int x,int flow,int ed) 75 { 76 int k,p,r=0; 77 if(x==ed) return flow; 78 for(int i=first[x];i!=-1;i=a[i].next) 79 { 80 int y=a[i].y; 81 if(d[y]==d[x]+1 && a[i].d>0) 82 { 83 p=minn(a[i].d,flow-r); 84 p=dfs(y,p,ed); 85 r+=p; 86 a[i].d-=p; 87 a[i^1].d+=p; 88 } 89 } 90 if(!r) d[x]=-1; 91 return r; 92 } 93 94 int dinic(int st,int ed) 95 { 96 int ans=0; 97 while(bfs(st,ed)) 98 { 99 int k; 100 while(k=dfs(st,INF,ed)) ans+=k; 101 } 102 return ans; 103 } 104 105 int main() 106 { 107 int T; 108 scanf("%d",&T); 109 while(T--) 110 { 111 scanf("%d%d",&n,&m); 112 int x,y,z,k; 113 char c; 114 s=n+m+1;t=s+1;ss=t+1;tt=ss+1; 115 len=-1;sum=0;bk=1; 116 memset(first,-1,sizeof(first)); 117 memset(map[0],0,sizeof(map[0])); 118 memset(map[1],63,sizeof(map[1])); 119 memset(p,0,sizeof(p)); 120 int sum1=0,sum2=0; 121 for(int i=1;i<=n;i++) 122 { 123 scanf("%d",&x); 124 map[0][s][i]=map[1][s][i]=x; 125 make_edge(s,i); 126 sum1+=x; 127 } 128 for(int i=n+1;i<=n+m;i++) 129 { 130 scanf("%d",&x); 131 map[0][i][t]=map[1][i][t]=x; 132 make_edge(i,t); 133 sum2+=x; 134 } 135 if(sum1!=sum2) bk=0; 136 scanf("%d",&k); 137 for(int i=1;i<=k;i++) 138 { 139 scanf("%d%d",&x,&y);getchar(); 140 scanf("%c%d",&c,&z); 141 if(x && y) build(c,x,y+n,z); 142 if(!x && y) 143 for(int j=1;j<=n;j++) 144 build(c,j,y+n,z); 145 if(x && !y) 146 for(int j=1;j<=m;j++) 147 build(c,x,j+n,z); 148 if(!x && !y) 149 for(int j=1;j<=n;j++) 150 for(int l=1;l<=m;l++) 151 build(c,j,l+n,z); 152 } 153 for(int i=1;i<=n;i++) 154 for(int j=n+1;j<=n+m;j++) 155 make_edge(i,j); 156 ins(t,s,INF); 157 if(!bk || dinic(ss,tt)!=sum) printf("IMPOSSIBLE\n"); 158 else 159 { 160 for(int i=0;i<len;i++) 161 { 162 x=a[i].x;y=a[i].y; 163 if(x<=n+m && y<=n+m) 164 { 165 if(!p[x][y-n]) p[x][y-n]=map[0][x][y]+a[i^1].d; 166 } 167 } 168 for(int i=1;i<=n;i++) 169 { 170 for(int j=1;j<=m;j++) 171 printf("%d ",p[i][j]); 172 printf("\n"); 173 } 174 } 175 printf("\n"); 176 } 177 return 0; 178 } poj2396 #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std;const int N=1100,M=5100,K=110,INF=(int)1e9; int s,t,len,fl,cl,pre[N],dis[N],flow[N],first[N]; bool in[N]; struct node{int x,y,d,f,next; }a[51000]; queue<int> q;int minn(int x,int y){return x<y ? x:y;}void ins(int x,int y,int d,int f) {a[++len].x=x;a[len].y=y;a[len].d=d;a[len].f=f;a[len].next=first[x];first[x]=len;a[++len].x=y;a[len].y=x;a[len].d=0;a[len].f=-f;a[len].next=first[y];first[y]=len; }int bfs(int st,int ed) {while(!q.empty()) q.pop();memset(pre,-1,sizeof(pre));memset(dis,63,sizeof(dis));memset(in,0,sizeof(in));memset(flow,0,sizeof(flow));pre[st]=0;dis[st]=0;in[st]=1;flow[st]=INF;q.push(st);while(!q.empty()){int x=q.front();in[x]=0;q.pop();for(int i=first[x];i!=-1;i=a[i].next){int y=a[i].y;if(a[i].d && dis[y]>dis[x]+a[i].f){dis[y]=dis[x]+a[i].f;pre[y]=i;flow[y]=minn(a[i].d,flow[x]);if(!in[y]) {in[y]=1;q.push(y);}}}}if(pre[ed]==-1) return -1;return flow[ed]; }void MFMC(int st,int ed)//max flow min cost {int k,p;fl=0,cl=0;while((k=bfs(st,ed))!=-1){fl+=k;cl+=dis[ed]*k;p=ed;while(p!=st){a[pre[p]].d-=k;a[pre[p]^1].d+=k;p=a[pre[p]].x;}} }int main() {int n,m,kk;while(scanf("%d%d%d",&n,&m,&kk)!=EOF){int x,y,d,f;len=-1;memset(first,-1,sizeof(first));for(int i=1;i<=m;i++){scanf("%d%d%d%d",&x,&y,&f,&d);for(int j=1;j<=d;j++)ins(x,y,1,f*(2*j-1));}s=n+1,t=n;ins(s,1,kk,0);MFMC(s,t);// printf("fl = %d cl = %d\n",fl,cl);if(fl==kk) printf("%d\n",cl);else printf("-1\n");}return 0; } LA5095 1 // 方法一 把每個詢問看成一個點,然后A的詢問連源點,B的詢問連匯點,如果AB間的某個 2 // 詢問有矛盾就在它們中間連一條無限大的邊,ans=sum-最小割。 3 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cstring> 7 #include<iostream> 8 #include<queue> 9 #include<vector> 10 using namespace std; 11 12 const int N=300100,INF=(int)1e9; 13 int s,t,len,num; 14 int first[2*N],dis[2*N]; 15 int A[N],B[N],p1[N],p2[N]; 16 // bool vis[2*N]; 17 bool vis[3100][3100]; 18 struct node{ 19 int x,y,d,next; 20 }a[6*N]; 21 queue<int> q; 22 23 int minn(int x,int y){return x<y ? x:y;} 24 int maxx(int x,int y){return x>y ? x:y;} 25 26 void ins(int x,int y,int d) 27 { 28 a[++len].x=x;a[len].y=y;a[len].d=d; 29 a[len].next=first[x];first[x]=len; 30 a[++len].x=y;a[len].y=x;a[len].d=0; 31 a[len].next=first[y];first[y]=len; 32 } 33 34 bool bfs(int st,int ed) 35 { 36 while(!q.empty()) q.pop(); 37 memset(dis,-1,sizeof(dis)); 38 dis[st]=0; 39 q.push(st); 40 while(!q.empty()) 41 { 42 int x=q.front();q.pop(); 43 for(int i=first[x];i!=-1;i=a[i].next) 44 { 45 int y=a[i].y; 46 if(dis[y]==-1 && a[i].d>0) 47 { 48 dis[y]=dis[x]+1; 49 q.push(y); 50 } 51 } 52 } 53 return (dis[ed]!=-1); 54 } 55 56 int dfs(int x,int ed,int flow) 57 { 58 int r=0,p; 59 if(x==ed) return flow; 60 for(int i=first[x];i!=-1;i=a[i].next) 61 { 62 int y=a[i].y; 63 if(dis[y]==dis[x]+1 && a[i].d>0) 64 { 65 p=minn(a[i].d,flow-r); 66 p=dfs(y,ed,p); 67 r+=p; 68 a[i].d-=p; 69 a[i^1].d+=p; 70 } 71 } 72 if(!r) dis[x]=-1; 73 return r; 74 } 75 76 int dinic(int st,int ed) 77 { 78 int ans=0; 79 while(bfs(st,ed)) 80 { 81 int p; 82 while(p=dfs(st,ed,INF)) ans+=p; 83 } 84 return ans; 85 } 86 87 int main() 88 { 89 int T,cas=0; 90 scanf("%d",&T); 91 while(T--) 92 { 93 len=-1; 94 memset(first,-1,sizeof(first)); 95 memset(A,0,sizeof(A)); 96 memset(B,0,sizeof(B)); 97 memset(vis,0,sizeof(vis)); 98 int n,m,sum=0,mx=0,num=300001; 99 scanf("%d",&n); 100 for(int i=1;i<=n;i++) 101 { 102 scanf("%d",&p1[i]); 103 sum+=p1[i]; 104 int x;num++; 105 while(1) 106 { 107 char c; 108 scanf("%d%c",&x,&c); 109 A[x]=i; 110 mx=maxx(mx,x); 111 if(c=='\n') break; 112 } 113 } 114 scanf("%d",&m); 115 s=0,t=n+m+1; 116 for(int i=1;i<=m;i++) 117 { 118 scanf("%d",&p2[i]); 119 sum+=p2[i];num++; 120 int x; 121 while(1) 122 { 123 char c; 124 scanf("%d%c",&x,&c); 125 B[x]=i; 126 mx=maxx(mx,x); 127 if(c=='\n') break; 128 } 129 } 130 for(int i=1;i<=n;i++) ins(s,i,p1[i]); 131 for(int i=1;i<=m;i++) ins(i+n,t,p2[i]); 132 for(int i=1;i<=mx;i++) 133 { 134 if(!A[i]||!B[i]||vis[A[i]][B[i]]) continue; 135 vis[A[i]][B[i]]=true; 136 ins(A[i],B[i]+n,INF); 137 } 138 printf("Case %d:\n",++cas); 139 printf("%d\n",sum-dinic(s,t)); 140 if(T) printf("\n"); 141 } 142 return 0; 143 } LA3487-方法一 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 #include<vector> 7 using namespace std; 8 9 const int N=300100,INF=(int)1e9; 10 int s,t,len,num; 11 int first[2*N],dis[2*N]; 12 int A[N],B[N]; 13 bool vis[3100][3100]; 14 struct node{ 15 int x,y,d,next; 16 }a[6*N]; 17 queue<int> q; 18 19 int minn(int x,int y){return x<y ? x:y;} 20 int maxx(int x,int y){return x>y ? x:y;} 21 22 void ins(int x,int y,int d) 23 { 24 a[++len].x=x;a[len].y=y;a[len].d=d; 25 a[len].next=first[x];first[x]=len; 26 a[++len].x=y;a[len].y=x;a[len].d=0; 27 a[len].next=first[y];first[y]=len; 28 } 29 30 bool bfs(int st,int ed) 31 { 32 while(!q.empty()) q.pop(); 33 memset(dis,-1,sizeof(dis)); 34 dis[st]=0; 35 q.push(st); 36 while(!q.empty()) 37 { 38 int x=q.front();q.pop(); 39 for(int i=first[x];i!=-1;i=a[i].next) 40 { 41 int y=a[i].y; 42 if(dis[y]==-1 && a[i].d>0) 43 { 44 dis[y]=dis[x]+1; 45 q.push(y); 46 } 47 } 48 } 49 return (dis[ed]!=-1); 50 } 51 52 int dfs(int x,int ed,int flow) 53 { 54 int r=0,p; 55 if(x==ed) return flow; 56 for(int i=first[x];i!=-1;i=a[i].next) 57 { 58 int y=a[i].y; 59 if(dis[y]==dis[x]+1 && a[i].d>0) 60 { 61 p=minn(a[i].d,flow-r); 62 p=dfs(y,ed,p); 63 r+=p; 64 a[i].d-=p; 65 a[i^1].d+=p; 66 } 67 } 68 if(!r) dis[x]=-1; 69 return r; 70 } 71 72 int dinic(int st,int ed) 73 { 74 int ans=0; 75 while(bfs(st,ed)) 76 { 77 int p; 78 while(p=dfs(st,ed,INF)) ans+=p; 79 } 80 return ans; 81 } 82 83 int main() 84 { 85 int T,cas=0; 86 scanf("%d",&T); 87 while(T--) 88 { 89 len=-1; 90 memset(first,-1,sizeof(first)); 91 memset(A,0,sizeof(A)); 92 memset(B,0,sizeof(B)); 93 memset(vis,0,sizeof(vis)); 94 int n,m,p,sum=0,mx=0,num=300001; 95 scanf("%d",&n); 96 for(int i=1;i<=n;i++) 97 { 98 scanf("%d",&p); 99 sum+=p; 100 int x;num++; 101 ins(0,num,p); 102 while(1) 103 { 104 char c; 105 scanf("%d%c",&x,&c); 106 ins(num,x+1,INF); 107 if(c=='\n') break; 108 } 109 } 110 scanf("%d",&m); 111 s=0,t=1; 112 for(int i=1;i<=m;i++) 113 { 114 scanf("%d",&p); 115 sum+=p;num++; 116 ins(num,t,p); 117 int x; 118 while(1) 119 { 120 char c; 121 scanf("%d%c",&x,&c); 122 ins(x+1,num,INF); 123 if(c=='\n') break; 124 } 125 } 126 // for(int i=1;i<=n;i++) ins(s,i,p1[i]); 127 // for(int i=1;i<=m;i++) ins(i+n,t,p2[i]); 128 for(int i=1;i<=mx;i++) 129 { 130 if(!A[i]||!B[i]||vis[A[i]][B[i]]) continue; 131 vis[A[i]][B[i]]=true; 132 ins(A[i],B[i]+n,INF); 133 } 134 printf("Case %d:\n",++cas); 135 printf("%d\n",sum-dinic(s,t)); 136 if(T) printf("\n"); 137 } 138 return 0; 139 } LA3487-方法二 #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> using namespace std;const int N=50*2,INF=(int)1e9; char ss[N][N]; int s,t,n,A,B,fl,cl,len,must_have,first[N],flow[N],dis[N],pre[N],s1[N],s2[N]; bool in[N]; struct node{int x,y,d,f,next; }a[2*N*N]; queue<int> q; int minn(int x,int y){return x<y ? x:y;} int maxx(int x,int y){return x>y ? x:y;}void ins(int x,int y,int d,int f) {a[++len].x=x;a[len].y=y;a[len].d=d;a[len].f=f;a[len].next=first[x];first[x]=len;a[++len].x=y;a[len].y=x;a[len].d=0;a[len].f=-f;a[len].next=first[y];first[y]=len; }int bfs(int st,int ed) {while(!q.empty()) q.pop();memset(dis,63,sizeof(dis));memset(flow,0,sizeof(flow));memset(in,0,sizeof(in));memset(pre,-1,sizeof(pre));q.push(st);in[st]=1;dis[st]=0;flow[st]=INF;pre[st]=0;while(!q.empty()){int x=q.front();in[x]=0;q.pop();for(int i=first[x];i!=-1;i=a[i].next){int y=a[i].y;if(a[i].d>0 && dis[y]>dis[x]+a[i].f){dis[y]=dis[x]+a[i].f;pre[y]=i;flow[y]=minn(flow[x],a[i].d);if(!in[y]) in[y]=1,q.push(y);}}}if(pre[ed]==-1) return 0;return flow[ed]; }void dinic(int st,int ed) {int k;fl=0,cl=0;while(k=bfs(st,ed)){fl+=k;cl+=dis[ed]*k;int p=ed;while(p!=st){a[pre[p]].d-=k;a[pre[p]^1].d+=k;p=a[pre[p]].x;}} }bool check()//如果答案是0 {int mx=0;memset(s1,0,sizeof(s1));memset(s2,0,sizeof(s2));for(int i=1;i<=n;i++)for(int j=0;j<n;j++)if(ss[i][j]=='C') must_have++,s1[i]++,s2[j+1]++,mx=maxx(mx,maxx(s1[i],s2[j+1])); for(int i=1;i<=n;i++) if(s1[i]!=s2[i]) return 0;if(must_have*A<mx*B) return 0; return 1; }int main() {int T=0;while(1){scanf("%d%d%d",&n,&A,&B);if(!n && !A && !B) return 0;s=0,t=2*n+1;must_have=0;for(int i=1;i<=n;i++)scanf("%s",ss[i]);int mx,sum,bk=0;int ans=-1;if(check()) bk=1,ans=must_have;for(int k=n;k>=1;k--){mx=0,sum=0;len=-1;memset(first,-1,sizeof(first));for(int i=1;i<=n;i++){for(int j=0;j<n;j++){int x=i,y=j+1+n;if(ss[i][j]=='.') ins(x,y,1,0); if(ss[i][j]=='C'){sum++;ins(s,y,1,0);ins(x,t,1,0); }}}for(int i=1;i<=n;i++){int x=i+n,y=i;ins(y,x,k,1);sum+=k;mx+=k;ins(s,y,k,0),ins(x,t,k,0);}dinic(s,t);mx-=cl;if(sum>fl) continue;if(mx && mx*A<k*B) continue;bk=1;ans=maxx(ans,mx);}printf("Case %d: ",++T);if(!bk) printf("impossible\n");else printf("%d\n",ans-must_have);}return 0; } LA5131 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=400,INF=(int)1e9; 9 int s,t,n,len,fl,cl,first[N],dis[N],pre[N],flow[N]; 10 bool in[N]; 11 struct node{ 12 int x,y,d,f,next; 13 }a[N*N]; 14 queue<int> q; 15 16 int minn(int x,int y){return x<y ? x:y;} 17 18 void ins(int x,int y,int d,int f) 19 { 20 a[++len].x=x;a[len].y=y;a[len].d=d;a[len].f=f; 21 a[len].next=first[x];first[x]=len; 22 a[++len].y=x;a[len].x=y;a[len].d=0;a[len].f=-f; 23 a[len].next=first[y];first[y]=len; 24 } 25 26 bool bfs(int st,int ed) 27 { 28 while(!q.empty()) q.pop(); 29 memset(dis,-1,sizeof(dis)); 30 memset(flow,0,sizeof(flow)); 31 memset(pre,-1,sizeof(pre)); 32 memset(in,0,sizeof(in)); 33 q.push(st); 34 in[st]=1,dis[st]=0,flow[st]=INF; 35 while(!q.empty()) 36 { 37 int x=q.front();in[x]=0;q.pop(); 38 for(int i=first[x];i!=-1;i=a[i].next) 39 { 40 int y=a[i].y; 41 if(a[i].d && dis[y]<dis[x]+a[i].f) 42 { 43 dis[y]=dis[x]+a[i].f; 44 flow[y]=minn(a[i].d,flow[x]); 45 pre[y]=i; 46 if(!in[y]) in[y]=1,q.push(y); 47 } 48 } 49 } 50 return flow[ed]; 51 } 52 53 void MCML(int st,int ed) 54 { 55 int k; 56 fl=0;cl=0; 57 while(k=bfs(st,ed)) 58 { 59 cl+=dis[ed]*k; 60 fl+=k; 61 int p=ed; 62 while(p!=st) 63 { 64 a[pre[p]].d-=k; 65 a[pre[p]^1].d+=k; 66 p=a[pre[p]].x; 67 } 68 } 69 } 70 71 int main() 72 { 73 while(1) 74 { 75 scanf("%d",&n); 76 if(!n) return 0; 77 len=-1; 78 memset(first,-1,sizeof(first)); 79 s=0,t=366; 80 for(int i=1;i<365;i++) ins(i,i+1,2,0); 81 ins(s,1,2,0);ins(365,t,2,0); 82 for(int i=1;i<=n;i++) 83 { 84 int x,y,d; 85 scanf("%d%d%d",&x,&y,&d); 86 if(x>y) swap(x,y); 87 ins(x,y+1,1,d); 88 } 89 MCML(s,t); 90 printf("%d\n",cl); 91 } 92 return 0; 93 } LA2796 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=3000,INF=(int)1e9; 9 char ss[N]; 10 int n,m,s,t,len,ct,dis[N],first[N]; 11 bool in[N]; 12 struct node{ 13 int x,y,d,next; 14 }a[100100]; 15 queue<int> q; 16 17 int idx(int x,int y){return (x-1)*m+y;} 18 int minn(int x,int y){return x<y ? x:y;} 19 20 void ins(int x,int y,int d) 21 { 22 a[++len].x=x;a[len].y=y;a[len].d=d; 23 a[len].next=first[x];first[x]=len; 24 a[++len].y=x;a[len].x=y;a[len].d=0; 25 a[len].next=first[y];first[y]=len; 26 } 27 28 bool bfs(int st,int ed) 29 { 30 while(!q.empty()) q.pop(); 31 memset(dis,-1,sizeof(dis)); 32 memset(in,0,sizeof(in)); 33 q.push(st);dis[st]=0;in[st]=1; 34 while(!q.empty()) 35 { 36 int x=q.front();in[x]=0;q.pop(); 37 for(int i=first[x];i!=-1;i=a[i].next) 38 { 39 int y=a[i].y; 40 if(a[i].d && dis[y]==-1) 41 { 42 dis[y]=dis[x]+1; 43 if(!in[y]) in[y]=1,q.push(y); 44 } 45 } 46 } 47 return (dis[ed]!=-1); 48 } 49 50 int dfs(int x,int ed,int flow) 51 { 52 int r=0; 53 if(x==ed) return flow; 54 for(int i=first[x];i!=-1;i=a[i].next) 55 { 56 int y=a[i].y; 57 if(a[i].d && dis[y]==dis[x]+1) 58 { 59 int p=minn(a[i].d,flow-r); 60 p=dfs(y,ed,p); 61 r+=p; 62 a[i].d-=p; 63 a[i^1].d+=p; 64 } 65 if(r==flow) break; 66 } 67 if(!r) dis[x]=-1; 68 return r; 69 } 70 71 int dinic(int st,int ed) 72 { 73 int k,ans=0; 74 while(bfs(st,ed)) 75 ans+=dfs(st,ed,INF); 76 return ans; 77 } 78 79 int main() 80 { 81 int T; 82 scanf("%d",&T); 83 while(T--) 84 { 85 int d,f,b; 86 scanf("%d%d",&m,&n); 87 s=0,t=n*m+1;ct=0; 88 scanf("%d%d%d",&d,&f,&b); 89 len=-1; 90 memset(first,-1,sizeof(first)); 91 for(int i=1;i<=n;i++) 92 { 93 scanf("%s",ss+1); 94 for(int j=1;j<=m;j++) 95 { 96 int x=idx(i,j),y1=idx(i-1,j),y2=idx(i,j-1); 97 if(ss[j]=='.' && (i==1 || i==n || j==1 || j==m)) 98 ct+=f,ss[j]='#'; 99 if(ss[j]=='.') 100 { 101 ins(s,x,f);ins(x,t,0); 102 if(i-1>=1) ins(x,y1,b),ins(y1,x,b); 103 if(j-1>=1) ins(x,y2,b),ins(y2,x,b); 104 } 105 if(ss[j]=='#') 106 { 107 ins(s,x,0); 108 if(i==1 || i==n || j==1 || j==m) ins(x,t,INF); 109 else ins(x,t,d); 110 if(i-1>=1) ins(x,y1,b),ins(y1,x,b); 111 if(j-1>=1) ins(x,y2,b),ins(y2,x,b); 112 } 113 } 114 } 115 printf("%d\n",ct+dinic(s,t)); 116 } 117 return 0; 118 } uva1515 #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> using namespace std;const int N=110,INF=(int)1e9; int s,t,sum,fl,cl,len,first[N],pre[N],flow[N],dis[N]; bool bk,in[N]; struct node {int x,y,d,f,next; }a[100010]; queue<int> q;int minn(int x,int y){return x<y ? x:y;} int A(int x){return x*2-1;} int B(int x){return x*2;}void ins(int x,int y,int d,int f) {a[++len].x=x;a[len].y=y;a[len].d=d;a[len].f=f;a[len].next=first[x];first[x]=len;a[++len].y=x;a[len].x=y;a[len].d=0;a[len].f=-f;a[len].next=first[y];first[y]=len; }void addedge(int x,int y,int k1,int k2,int f) {sum+=k2;//(x,y,k1,k1,f);if(k1){ins(s,y,k1,f);ins(x,t,k1,f); }//(x,y,0,k2-k1,f);if(k2!=k1){ins(s,y,k2-k1,0);ins(y,x,k2-k1,-f);ins(x,t,k2-k1,f); } }int bfs(int st,int ed) {while(!q.empty()) q.pop();memset(in,0,sizeof(in));memset(dis,63,sizeof(dis));memset(flow,0,sizeof(flow));memset(pre,-1,sizeof(pre));q.push(st);dis[st]=0;flow[st]=INF;in[st]=1;while(!q.empty()){int x=q.front();in[x]=0;q.pop();for(int i=first[x];i!=-1;i=a[i].next){int y=a[i].y;if(a[i].d && dis[y]>dis[x]+a[i].f){dis[y]=dis[x]+a[i].f;flow[y]=minn(flow[x],a[i].d);pre[y]=i;if(!in[y]) in[y]=1,q.push(y);}}}return flow[ed]; }void dinic(int st,int ed) {int k;fl=0;cl=0;while(k=bfs(st,ed)){bk=1;fl+=k;cl+=dis[ed]*k;int p=ed;while(p!=st){a[pre[p]].d-=k;a[pre[p]^1].d+=k;p=a[pre[p]].x;}} }int main() {int T,n,m,k;scanf("%d",&T);while(T--){scanf("%d%d%d",&n,&m,&k);len=-1;sum=0;memset(first,-1,sizeof(first));s=0,t=2*n+1;for(int i=1;i<=n;i++)addedge(A(i),B(i),k,k,0);for(int i=1;i<=m;i++){int x,y,d;scanf("%d%d%d",&x,&y,&d);x++,y++;addedge(B(x),A(y),0,1,d);}// for(int i=0;i<len;i+=2)// printf("%d --> %d d = %d f = %d\n",a[i].x,a[i].y,a[i].d,a[i].f); dinic(s,t);if(fl==sum) printf("%d\n",cl);else printf("-1\n");}return 0; } LA2197 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=300,INF=(int)1e9; 9 int s,t,len,first[N],dis[N],fa[N]; 10 bool c[N][N]; 11 struct node{ 12 int x,y,d,next; 13 }a[100010]; 14 queue<int> q; 15 16 int minn(int x,int y){return x<y ? x:y;} 17 18 int findfa(int x) 19 { 20 if(fa[x]!=x) fa[x]=findfa(fa[x]); 21 return fa[x]; 22 } 23 24 void ins(int x,int y) 25 { 26 a[++len].x=x;a[len].y=y;a[len].d=1; 27 a[len].next=first[x];first[x]=len; 28 a[++len].x=y;a[len].y=x;a[len].d=0; 29 a[len].next=first[y];first[y]=len; 30 } 31 32 int bfs(int st,int ed) 33 { 34 while(!q.empty()) q.pop(); 35 memset(dis,-1,sizeof(dis)); 36 q.push(st); 37 dis[st]=0; 38 while(!q.empty()) 39 { 40 int x=q.front();q.pop(); 41 for(int i=first[x];i!=-1;i=a[i].next) 42 { 43 int y=a[i].y; 44 if(a[i].d && dis[y]==-1) 45 { 46 dis[y]=dis[x]+1; 47 q.push(y); 48 } 49 } 50 } 51 return (dis[ed]!=-1); 52 } 53 54 int dfs(int x,int ed,int flow) 55 { 56 int r=0,p; 57 if(x==ed) return flow; 58 for(int i=first[x];i!=-1;i=a[i].next) 59 { 60 int y=a[i].y; 61 if(dis[y]==dis[x]+1 && a[i].d) 62 { 63 p=minn(flow-r,a[i].d); 64 p=dfs(y,ed,p); 65 r+=p; 66 a[i].d-=p; 67 a[i^1].d+=p; 68 } 69 if(r==flow) break; 70 } 71 if(!r) dis[x]=-1; 72 return r; 73 } 74 75 int dinic(int st,int ed) 76 { 77 int k,ans=0; 78 while(k=bfs(st,ed)) 79 ans+=dfs(st,ed,INF); 80 return ans; 81 } 82 83 int main() 84 { 85 int T; 86 scanf("%d",&T); 87 while(T--) 88 { 89 int n,m1,m2,x,y; 90 scanf("%d%d%d",&n,&m1,&m2); 91 s=0,t=2*n+1,len=-1; 92 memset(first,-1,sizeof(first)); 93 memset(c,0,sizeof(c)); 94 for(int i=1;i<=n;i++) fa[i]=i; 95 for(int i=1;i<=m1;i++) 96 { 97 scanf("%d%d",&x,&y); 98 c[x][y]=1; 99 } 100 for(int i=1;i<=m2;i++) 101 { 102 scanf("%d%d",&x,&y); 103 fa[findfa(x)]=findfa(y); 104 } 105 for(int i=1;i<=n;i++) fa[i]=findfa(i); 106 for(int i=1;i<=n;i++) 107 for(int j=1;j<=n;j++) 108 { 109 if(c[i][j]) ins(i,n+j); 110 else 111 { 112 for(int k=1;k<=n;k++) 113 if(fa[i]==fa[k] && c[k][j]) {ins(i,n+j);break;} 114 } 115 } 116 int rl=len; 117 for(int i=1;i<=n;i++) ins(s,i); 118 for(int i=n+1;i<=2*n;i++) ins(i,t); 119 // for(int i=0;i<=len;i+=2) printf("%d -- > %d %d\n",a[i].x,a[i].y,a[i].d); 120 int l=0,r=n*n; 121 while(l!=r) 122 { 123 int k=(l+r+1)>>1; 124 for(int i=0;i<=rl;i+=2) a[i].d=1,a[i^1].d=0; 125 for(int i=rl+1;i<=len;i+=2) a[i].d=k,a[i^1].d=0; 126 if(dinic(s,t)==n*k) l=k; 127 else r=k-1; 128 } 129 printf("%d\n",l); 130 } 131 return 0; 132 } hdu3081 1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 8 const int N=110,M=550,INF=(int)1e9; 9 int s,t,sl,len,first[N],dis[N],in[N],out[N],g[N],sk[N]; 10 bool vis[N]; 11 struct node{ 12 int x,y,d,next,id; 13 bool temp,bk; 14 }a[100010],b[M]; 15 queue<int> q; 16 int minn(int x,int y){return x<y ? x:y;} 17 18 void ins(int x,int y,int d,bool p) 19 { 20 a[++len].x=x;a[len].y=y;a[len].d=d; 21 a[len].next=first[x];first[x]=len; 22 if(!p) 23 { 24 a[++len].y=x;a[len].x=y;a[len].d=0; 25 a[len].next=first[y];first[y]=len; 26 } 27 } 28 29 bool bfs(int st,int ed) 30 { 31 while(!q.empty()) q.pop(); 32 memset(dis,-1,sizeof(dis)); 33 q.push(st);dis[st]=0; 34 while(!q.empty()) 35 { 36 int x=q.front();q.pop(); 37 for(int i=first[x];i!=-1;i=a[i].next) 38 { 39 int y=a[i].y; 40 if(a[i].d && dis[y]==-1) 41 { 42 dis[y]=dis[x]+1; 43 q.push(y); 44 } 45 } 46 } 47 return (dis[ed]!=-1); 48 } 49 50 int dfs(int x,int ed,int flow) 51 { 52 int r=0; 53 if(x==ed) return flow; 54 for(int i=first[x];i!=-1;i=a[i].next) 55 { 56 int y=a[i].y; 57 if(dis[y]==dis[x]+1 && a[i].d) 58 { 59 int p=minn(flow-r,a[i].d); 60 p=dfs(y,ed,p); 61 r+=p; 62 a[i].d-=p; 63 a[i^1].d+=p; 64 } 65 if(r==flow) break; 66 } 67 if(r==0) dis[x]=-1; 68 return r; 69 } 70 71 int dinic(int st,int ed) 72 { 73 int k,ans=0; 74 while(k=bfs(st,ed)) 75 ans+=dfs(st,ed,INF); 76 return ans; 77 } 78 79 void find(int x) 80 { 81 for(int i=first[x];i!=-1;i=a[i].next) 82 { 83 int y=a[i].y; 84 if(!vis[y] || !a[i].bk) continue; 85 a[i].bk=0; 86 find(y); 87 } 88 sk[++sl]=x,vis[x]=0; 89 } 90 91 int main() 92 { 93 int T,n,m,sum,cas=0;char c;bool bk; 94 scanf("%d",&T); 95 while(T--) 96 { 97 bk=1; 98 scanf("%d%d",&n,&m); 99 len=-1; 100 memset(first,-1,sizeof(first)); 101 memset(in,0,sizeof(in)); 102 memset(out,0,sizeof(out)); 103 s=0,t=n+1;sum=0; 104 for(int i=1;i<=m;i++) 105 { 106 scanf("%d%d %c",&b[i].x,&b[i].y,&c); 107 in[b[i].y]++;out[b[i].x]++; 108 if(c=='U') b[i].temp=1; 109 else b[i].temp=0; 110 b[i].bk=0; 111 } 112 for(int i=1;i<=n;i++) 113 { 114 int d=in[i]-out[i]; 115 if(d&1) {bk=0;break;} 116 if(d<0) ins(s,i,(-d)/2,0),sum+=(-d)/2; 117 if(d>0) ins(i,t,d/2,0); 118 } 119 if(bk) 120 { 121 for(int i=1;i<=m;i++) 122 { 123 if(!b[i].temp) continue; 124 ins(b[i].x,b[i].y,1,0); 125 b[i].id=len-1; 126 } 127 if(dinic(s,t)!=sum) bk=0; 128 } 129 if(cas) printf("\n");cas++; 130 if(!bk) printf("No euler circuit exist\n"); 131 else 132 { 133 for(int i=1;i<=m;i++) 134 { 135 if(b[i].temp) b[i].bk=a[b[i].id].d; 136 else b[i].bk=1; 137 } 138 len=-1; 139 memset(first,-1,sizeof(first)); 140 for(int i=1;i<=m;i++) 141 if(b[i].bk) ins(b[i].x,b[i].y,1,1); 142 else ins(b[i].y,b[i].x,1,1); 143 sl=0;memset(vis,1,sizeof(vis)); 144 for(int i=0;i<=len;i++) a[i].bk=1; 145 find(1); 146 for(int i=sl;i>=1;i--) printf("%d ",sk[i]);printf("\n"); 147 } 148 } 149 return 0; 150 } uva10735?
| 題號 | 題目 | 題意 | 題解 | 備注 |
| poj2396 | Budget | 一個n*m的矩陣,給定每一行的和以及每一列的和,然后給定多個限制,即某個格子的上下界,要求一個可行的方案。 | 建n個點表示行,m個點表示列,原圖源匯點s、t。 s連到表示第i行的點,上下界都為sum[i](行) 表示第i列的點連到t,上下界都為sum[i](列) 然后表示第i行的點x和表示第j行的點y中間連一條邊,上下界就是約束。 錯了很久,注意: 1.邊數要足夠大 2.p數組一開始沒有清空 3.dfs的優化(不斷找,用r儲存已用的流量)?快超級多。 | 上下界網絡流 可行流 矩陣模型 模板題 |
| LA5095 | Transportation | 一個n個點、m條邊的有向圖,1為起點,n為終點,要從起點運k個物體到終點,每條邊的費用與流量關系:f=ax^2,問最小費用。 | 重新開一個源點,源點到1有一條流量為k、費用為0的邊,然后跑最小費用最大流,如果最大流等于k則可行。 | 最小費用最大流 f=ax^i(i為自然數)模型 模板題 |
| LA3487 | Duopoly | A、B兩個公司要買一些資源(他們自己買的資源不會重復),一個資源只能賣給一個公司。問最大收益。 | ????方法一?把每個詢問看成一個點,然后A的詢問連源點,B的詢問連匯點,如果AB間的某個詢問有矛盾就在它們中間連一條無限大的邊,ans=sum-最小割。 ????方法二:對于每個詢問,新建一個點x,如果是A就源點連向這個點,流量為價錢p,然后連向這個詢問所要求買的資源c[i],流量為INF。 如果是B則反過來,連向匯點。 | 最小割 一個費用/流量對應多個點 模板題 |
| LA5131 | Chips?Challenge | 給定一個矩陣,每個格子有三種情況——不能填、能填、一定要填,要求填最多的格子,使第i行的總和等于第i列的總和,并且填的格子數不能大于總數的A/B。 | 構圖:在表示第i行的點x和表示第i列的點y間連一條(y,x)的邊,費用為1,然后跑最大費用流。 詳見博客。 | 最大費用循環流 模板題 |
| LA2796 | Concert?Hall?Scheduling | 你有2個房間,有365天,有n個人找你租房,第i個人要從第xi到第yi天要一個房(任意一個),付wi的錢,求怎樣安排收的錢最多 | ????建365個點,連(i,i+1,2,0)的邊(流量2(2個房間),費用0),源點連1,流量2費用0,365連匯點,流量2費用0。然后對于一個詢問(xi,yi,wi),連(xi,yi+1,2,wi)的邊,注意是yi+1,不然yi這個點可能同時作為別人的起點,然后重復就WA了。跑一遍最大費用流。 | 最大費用流 區間模型 |
| uva1515 | Pool?construction | 給一個m*n的矩陣,每個格子中是#和.兩個符號之一,分別代表草和洞?,F在要將洞給圍起來(將草和洞分離),每條邊需花費b元(即將一個洞包起來需要4邊,將2個連續的洞包起來需要6邊,省了2條邊)。有個特殊能力,能將洞變成草,花費f。當然也能將草變成洞,花費d。圍起洞來需要多少花費。矩陣四周最邊邊的格子都必須是草,即出現洞就必須轉草。 | s代表草,t代表洞; 對于每個點x,如果是草,建邊(s,x,0),(x,t,d); 如果是洞,建邊(s,x,f),(x,t,0)? 如果一定要選,那到另一個的流量就是INF(代價無窮大) 對于每對相鄰的點(x,y),建(x,y,b),(y,x,b) 這樣就可以保證當x、y是不同的東西,最小割的時候就必須加上b的代價,那就是洞包起來的代價。 | 二分圖模型 最小割 |
| LA2197 | Paint?the?Roads | n個點m條邊的帶權有向圖,現在要將某些邊涂上顏色,使得每個點恰好在k個有顏色的環上,總費用最小。 | 題意->每個點每一秒流入和流出的流量都是k->最小費用循環流 把一個點拆成兩個點,這兩個點之間連一條邊,上下界都是k,然后跑有上下界的最小費用循環流。 對于每條邊(x,y,k1,k2,f),拆成:(x,y,k1,k1,f)(再按上下界拆邊,即(s,y,k1,f)?(x,t,k1,f)),(y,x,k2-k1,-f),(s,y,k2-k1,0),(x,t,k2-f1,f),用k2的和判滿流。 | 最小費用循環流 拆點 |
| hdu3081 | Marriage?Match?II | n個女生與n個男生配對,每個女生只能配對某些男生,有些女生相互是朋友,每個女生也可以跟她朋友能配對的男生配對。 每次配對,每個女生都要跟不同的男生配對且每個女生都能配到對。問最多能配對幾輪。(n<=100) | 二分答案k,用并查集建邊,每對可配對的男生與女生之間連一條流量為1的邊,源點到每個女生連一條k的邊,匯點連每個男生,流量為k。跑最大流。 WA了一中午,對拍都看不出錯,然后是一個i打成了x,淚目。 | 最大流 二分 |
| uva10735 | Euler?Circuit | 給定一個混合圖(有有向邊和無向邊),然后要你求一條歐拉回路(遍歷所有邊后回到出發點)。 | 1.歐拉回路建圖,給無向邊定向。最終要是in[i]==out[i],那就先給無向邊隨便定向,d[i]=in[i]-out[i],若d[i]為奇數則無解(反一條邊,d[i]會變化2)。 ??對于d[i]>0,則最多要改d[i]/2條入邊,(i,t,d[i]/2) ??對于d[i]<0,則最多要該(-d[i])/2條出邊,(s,i,(-d[i])/2) ??每條無向邊最多更改一次,(x,y,1) ??跑最大流,滿流則有解。 2.輸出歐拉回路(套圈算法)。隨便從一個點開始遍歷,走出一個圈,但是有一些邊可能還沒走,又有一個圈。做法就是起點開始遍歷,dfs遍歷其相鄰的點,如果一個點沒有相鄰點了就壓到棧里。倒序輸出。 | 最大流 歐拉回路 構圖 |
轉載于:https://www.cnblogs.com/KonjakJuruo/p/5560129.html
總結
以上是生活随笔為你收集整理的【网络流】网络流小总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: unity 总结(一)
- 下一篇: 数据库SQL语句学习笔记(4)-过滤数据