TOJ 1684. Power Network 【第一道网络流 】

/*  第一道网络流。。。dinic做的,参考了别人程序。
 *  dinic之所以比较高效是因为它在BFS的时候给每个点赋了一个层次值,所以在每次寻找增广路进行增流的时候,
 *  可以顺着层次值递增进行,到达汇点以后可以回溯到某个可以继续增广的点继续增流直到找不到一条增广路,有效
 *  的利用了BFS所得到的信息。
 *  使用list的迭代器记录某次增流后残留量为0的点,便于进行回溯
 */

#include <cstdio> #include <cstring> #include <queue> #include <list> #define INF 0x1f1f1f1f #define MAXN 205 using namespace std; int n,m,nsrc,nsink; int src,sink; int restflow[MAXN][MAXN],level[MAXN];//残留网络的邻接矩阵,level数组记录层次 bool flag[MAXN]; inline void add_edge(int u,int v,int w){ restflow[u][v] = w; } inline void initial(){ // input and initialize char temp[500]; n += 2; //增加两个超级点 memset(restflow,0,sizeof(restflow)); src = 1; sink = n; int i,st,ed,w; for(i = 1;i <= m; ++i){ scanf("%s",temp); sscanf(temp,"(%d,%d)%d",&st,&ed,&w); add_edge(st+2,ed+2,w); } for(i = 1;i <= nsrc; ++i){ scanf("%s",temp); sscanf(temp,"(%d)%d",&ed,&w); add_edge(1,ed+2,w); } for(i = 1;i <= nsink; ++i){ scanf("%s",temp); sscanf(temp,"(%d)%d",&st,&w); add_edge(st+2,n,w); } } inline int hasflow(int x){ for(int i = 1;i <= n; ++i) if(restflow[x][i] && level[i] == level[x] + 1) return i; return 0; } inline bool BFS(){ queue<int>que; while(!que.empty()) que.pop(); bool mark = false; memset(flag,false,sizeof(flag)); for(int i = 1;i <= n; i++) level[i] = INF; que.push(src); flag[src] = true; level[src] = 0; while(!que.empty()){ int tep = que.front(); que.pop(); for(int i = 1;i <= n; ++i){ if(!flag[i] && restflow[tep][i] != 0){ flag[i] = true; level[i] = level[tep] + 1; que.push(i); } } if(tep == sink) mark = true; } return mark; } inline int dinic(){ int u,v,capflow,last,maxflow = 0; list<int>path; list<int>::iterator its; while(BFS()){ path.clear(); path.push_back(src); while(hasflow(src) != 0){ u = path.back(); if(u != sink){ if(v = hasflow(u)) //可增广 path.push_back(v); else{ path.pop_back(); level[u] = INF; } }else{ capflow = INF; for(its = path.begin(); its != path.end(); ++its){ u = *its; if((++its) == path.end()) break; v = *its; if(restflow[u][v] < capflow) capflow = restflow[u][v]; --its; } last = -1; maxflow += capflow; for(its = path.begin(); its != path.end(); ++its){ u = *its; if((++its) == path.end() ) break; v = *its; restflow[u][v] -= capflow; if(restflow[u][v] == 0 && last == -1) last = u; --its; } while(path.back() != last ) path.pop_back(); //等价于回溯到可增广的点,在新的循环里继续增流 } } } return maxflow; } int main() { while(scanf("%d%d%d%d",&n,&nsrc,&nsink,&m) != EOF){ initial(); printf("%d/n",dinic()); } }

你可能感兴趣的:(网络,list,iterator,input,NetWork)