标签:style bool back using 路径 ++ size 表示 amp
tips:
1.增光路---层叠相消---相当于改变
2.找到一条可行路,反向建边,改变原来的容量,形成残余网络
3.每条流的流量来源重新分配---也就是所说的可以反悔
4.三个性质证明反向边---中间结点流入==流出
5.G[u][v]=0---表示无边
4.ref:gw_netglow.pdf和紫书
//需要先补下图的bfs遍历 //poj1273 /*input 5 4 1 2 40 1 4 20 2 4 20 2 3 30 3 4 10 */ /*output 50 */ //#include<bits/stdc++.h> #include<iostream> #include<queue> using namespace std; int Prev[300];//路径上每个节点的前驱结点,联想并查集里 int G[300][300]; bool Visited[300]; int n,m; unsigned Augment(){ int v; int i; deque<int> q;//双向队列 memset(Prev,0,sizeof(Prev)); memset(Visited,0,sizeof(Visited)); Prev[1]=0; Visited[1]=1; q.push_back(1); bool bFindPath=false; //用bfs寻找一条源到汇的可行路径 while(!q.empty()){ v=q.front();q.pop_front(); for(int i=1;i<=m;i++){//m是顶点 if(G[v][i]>0 && Visited[i] == 0){ Prev[i]=v; Visited[i]=1; if(i == m){ bFindPath=true; q.clear(); break;//跳出while循环 } else q.push_back(i); } } } if(!bFindPath) return 0; int nMinFlow=0x3fffffff; v=m; //寻找路径上容量最小的边,其容量就是此次增加的流量 while(Prev[v]){ nMinFlow=min(nMinFlow,G[Prev[v]][v]); v=Prev[v]; } v=m; //沿此路径添加反向边,同时修改路径上的每条边的容量 while(Prev[v]){ G[Prev[v]][v]-=nMinFlow; G[v][Prev[v]]+=nMinFlow; v=Prev[v]; } return nMinFlow; } int main(){ while(cin>>n>>m){//n条边,m个顶点 int s,e,c; memset(G,0,sizeof(G));//邻接矩阵存图 for(int i=0;i<n;i++){ cin>>s>>e>>c; G[s][e]+=c;//两点间可能有多条边 } unsigned int Maxflow=0; unsigned int aug; while(aug=Augment())//还能找到增广路---直到不能找到增广路 Maxflow+=aug; cout<<Maxflow<<endl; } return 0; }
//被poj1455难住了o(╥﹏╥)o,神搜吖
标签:style bool back using 路径 ++ size 表示 amp
原文地址:https://www.cnblogs.com/SUMaywlx/p/9457893.html