最大流:
http://blog.csdn.net/brodrinkwater/article/details/54999932
https://www.cnblogs.com/LUO77/p/6115057.html
1 //ek算法 2 #include<algorithm> 3 #include<iostream> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 #include<queue> 9 #define ll long long 10 using namespace std; 11 int n,m,sum; 12 int c[501][501],r[501][501],p[501],pre[501]; 13 void find(){ 14 queue<int>q; 15 while(1){ 16 q.push(1); 17 memset(p,0,sizeof(p)); 18 p[1]=9999999; 19 while(!q.empty()){ 20 int ans=q.front(); 21 q.pop(); 22 for(int i=1;i<=n;i++){ 23 if(!p[i] && r[ans][i]<c[ans][i]){ 24 p[i]=min(p[ans],c[ans][i]-r[ans][i]); 25 pre[i]=ans; 26 q.push(i); 27 } 28 } 29 } 30 if(!p[n])break; 31 sum+=p[n]; 32 int tmp=n; 33 while(pre[tmp]){ 34 r[pre[tmp]][tmp]+=p[n]; 35 r[tmp][pre[tmp]]-=p[n]; 36 tmp=pre[tmp]; 37 } 38 39 } 40 return ; 41 } 42 int main(){ 43 scanf("%d%d",&n,&m); 44 for(int i=1;i<=m;i++){ 45 int x,y,z; 46 scanf("%d%d%d",&x,&y,&z); 47 c[x][y]+=z; 48 } 49 find(); 50 printf("%d",sum); 51 return 0; 52 }
1 #include<algorithm> 2 //dinic算法 3 #include<iostream> 4 #include<cstdlib> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 #include<queue> 9 #define ll long long 10 using namespace std; 11 int m,n,ans; 12 struct edge 13 { 14 int to,next,f; 15 }e[200005]; 16 int head[20005],p; 17 void addedge(int u,int v,int f) 18 { 19 e[p].to=v;e[p].f=f;e[p].next=head[u];head[u]=p;p++; 20 e[p].to=u;e[p].f=0;e[p].next=head[v];head[v]=p;p++; 21 } 22 int level[20005]; 23 bool bfs(int s,int t) 24 { 25 memset(level,0,sizeof(level)); 26 queue<int> q; 27 q.push(s); 28 level[s]=1; 29 while(!q.empty()) 30 { 31 int u=q.front(); 32 q.pop(); 33 if(t==u)return 1; 34 for(int i=head[u];i!=-1;i=e[i].next) 35 { 36 int v=e[i].to,f=e[i].f; 37 if(level[v]==0 && f!=0){ 38 q.push(v); 39 level[v]=level[u]+1; 40 } 41 } 42 } 43 return 0; 44 } 45 int dfs(int u,int maxf,int t) 46 { 47 if(u==t)return maxf; 48 int tmp=0; 49 for(int i=head[u];i!=-1 && tmp<maxf;i=e[i].next) 50 { 51 int v=e[i].to,f=e[i].f; 52 if(level[v]==level[u]+1 && f!=0) 53 { 54 int minn=min(maxf-tmp,f); 55 f=dfs(v,minn,t); 56 e[i].f-=f; //正向边 57 e[i^1].f+=f; //反向边 58 //这里的^是很常用的,因为前向星加边是两条一起加的,所以一个标号是奇数,一个是偶数,所以^1一下可以得到另一条边,比如0^1 = 1,1 ^ 1 = 0, 2^1 = 3,3 ^1 = 2; 59 tmp+=f; 60 } 61 } 62 if(!tmp)level[u]=1000000000; 63 return tmp; 64 } 65 void dinic(int s,int t) 66 { 67 while(bfs(s,t)){ 68 ans+=dfs(s,1000000000,t); 69 } 70 } 71 int main() 72 { 73 scanf("%d%d",&n,&m); 74 memset(head,-1,sizeof(head)); 75 for(int i=1;i<=m;i++) 76 { 77 int u,v,f; 78 scanf("%d%d%d",&u,&v,&f); 79 addedge(u,v,f); 80 } 81 dinic(1,n); 82 printf("%d",ans); 83 return 0; 84 }
最大流最小割定理:
http://hihocoder.com/problemset/problem/1378
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<queue> 8 #include<vector> 9 #define ll long long 10 using namespace std; 11 12 int m,n,ans,head[20005],p,level[20005],sum=0; 13 bool fa=false; 14 15 struct edge 16 { 17 int to,next,f; 18 }e[200005]; 19 20 vector <int> w; 21 22 void addedge(int u,int v,int f) 23 { 24 e[p].to=v;e[p].f=f;e[p].next=head[u];head[u]=p;p++; 25 e[p].to=u;e[p].f=0;e[p].next=head[v];head[v]=p;p++; 26 } 27 28 bool bfs(int s,int t) 29 { 30 memset(level,0,sizeof(level)); 31 queue<int> q; 32 q.push(s); 33 level[s]=1; 34 if(fa)w.push_back(s); 35 while(!q.empty()) 36 { 37 int u=q.front(); 38 q.pop(); 39 if(t==u)return 1; 40 for(int i=head[u];i!=-1;i=e[i].next) 41 { 42 int v=e[i].to,f=e[i].f; 43 if(level[v]==0 && f!=0){ 44 q.push(v); 45 level[v]=level[u]+1; 46 if(fa)w.push_back(v),sum++; 47 } 48 } 49 } 50 return 0; 51 } 52 53 int dfs(int u,int maxf,int t) 54 { 55 if(u==t)return maxf; 56 int tmp=0; 57 for(int i=head[u];i!=-1 && tmp<maxf;i=e[i].next) 58 { 59 int v=e[i].to,f=e[i].f; 60 if(level[v]==level[u]+1 && f!=0) 61 { 62 int minn=min(maxf-tmp,f); 63 f=dfs(v,minn,t); 64 e[i].f-=f; //正向边 65 e[i^1].f+=f; //反向边 66 //这里的^是很常用的,因为前向星加边是两条一起加的,所以一个标号是奇数,一个是偶数,所以^1一下可以得到另一条边,比如0^1 = 1,1 ^ 1 = 0, 2^1 = 3,3 ^1 = 2; 67 tmp+=f; 68 } 69 } 70 if(!tmp)level[u]=1000000000; 71 return tmp; 72 } 73 74 void dinic(int s,int t) 75 { 76 while(bfs(s,t)){ 77 ans+=dfs(s,1000000000,t); 78 } 79 } 80 81 int main() 82 { 83 scanf("%d%d",&n,&m); 84 memset(head,-1,sizeof(head)); 85 for(int i=1;i<=m;i++) 86 { 87 int u,v,f; 88 scanf("%d%d%d",&u,&v,&f); 89 addedge(u,v,f); 90 } 91 92 dinic(1,n); 93 printf("%d ",ans); 94 fa=true; 95 bfs(1,n); 96 printf("%d\n%d",sum+1,w[0]); 97 for(int i=1;i<w.size();i++)printf(" %d",w[i]); 98 99 return 0; 100 }