网络流--最大流
网络流的所有算法都是基于一种增广路的思想,下面首先简要的说一下增广路思想,其基本步骤如下:
1.找到一条从源点到汇点的路径,使得路径上任意一条边的残量>0(注意是大于而不是大于等于,这意味着这条边还可以分配流量),这条路径便称为增广路
2.找到这条路径上最小的F[u][v](我们设F[u][v]表示u->v这条边上的残量即剩余流量),下面记为flow
3.将这条路径上的每一条有向边u->v的残量减去flow,同时对于起反向边v->u的残量加上flow
4.重复上述过程,直到找不出增广路,此时我们就找到了最大流
最大流板子题,洛谷草地排水。先用bfs求出每个点深度,再用一个类似dfs的东西找到能新走到汇点的权值。多走几次就行了。
这有一个很棒的博客,大家可以看一看
https://www.cnblogs.com/SYCstudio/p/7260613.html
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; struct node { int x,y,c,next,other; }; node a[2110000]; int len = 0,last[5000],st,ed; int list[5000]; queue <int> qu; void add(int x,int y,int w) { int k1,k2; a[++len].next = last[x]; k1 = len; a[len].x = x; a[len].y = y; a[len].c = w; last[x] = len; a[++len].next = last[y]; k2 = len; a[len].x = y; a[len].y = x; a[len].c = 0; last[y] = len; a[k1].other = k2; a[k2].other = k1; } int h[5000]; bool bfs() { memset(h,0,sizeof(h)); h[st] = 1; int head,tail; list[1] = st; head = 1; tail = 2; while(head != tail) { int x = list[head]; // cout<<x<<endl; for(int k = last[x];k;k = a[k].next) { int y = a[k].y; // cout<<k<<" "<<a[k].c<<" "<<y<<endl; if(a[k].c > 0 && h[y] == 0) { h[y] = h[x] + 1; list[tail++] = y; // cout<<y<<endl; } } head++; } /*for(int i = 1;i <= ed;i++) cout<<h[i]<<" "; cout<<endl; for(int i = 1;i <= len;i++) cout<<a[i].c<<" "; cout<<endl;*/ if(h[ed] > 0) return true; else return false; } int mymin(int x,int y){return x < y ? x : y;} int find(int x,int f) { if(x == ed) return f; int s = 0,t; for(int k = last[x];k;k = a[k].next) { int y = a[k].y; if(s < f && h[y] == (h[x] + 1) && a[k].c > 0) { // cout<<a[k].c<<" "<<f - s<<endl; t = find(y,mymin(a[k].c,f - s)); s += t; // cout<<t<<endl; a[k].c -= t; a[a[k].other].c += t; // cout<<k<<"_"<<a[k].c<<" "<<a[k].other<<"_"<<a[a[k].other].c<<endl; } } if(s == 0) h[x] = 0; return s; } int main() { int n,m; cin>>m>>n; st = 1; ed = n; len = 0; memset(last,0,sizeof(last)); for(int i = 1;i <= m;i++) { int x,y,z; cin>>x>>y>>z; add(x,y,z); } // cout<<endl; int s = 0,t;int l = 0; while(bfs() == true) { s += find(st,99999999); } cout<<s; return 0; } /* 4 4 1 2 10 2 4 5 2 3 20 3 4 10 */
只想找一个不会伤害我的人