TOJ 1684. Power Network 【第一道网络流 】
2010-07-25 21:52
351 查看
/* 第一道网络流。。。dinic做的,参考了别人程序。
* dinic之所以比较高效是因为它在BFS的时候给每个点赋了一个层次值,所以在每次寻找增广路进行增流的时候,
* 可以顺着层次值递增进行,到达汇点以后可以回溯到某个可以继续增广的点继续增流直到找不到一条增广路,有效
* 的利用了BFS所得到的信息。
* 使用list的迭代器记录某次增流后残留量为0的点,便于进行回溯
*/
* 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()); } }
相关文章推荐
- POJ1459(Power Network)【网络流】
- 1459 Power Network 网络流 SAP
- POJ1459-Power Network-网络流-最大流(EK模板题)
- POJ训练计划1459_Power Network(网络流最大流/Dinic)
- POJ 1459 Power Network(网络流 最大流 多起点,多汇点)
- poj&nbsp;1459&nbsp;power&nbsp;network(网络流&nbsp;di…
- poj 1459 Power Network 网络流初步,增广路算法,主要是建图麻烦
- poj1459 Power Network网络流最大流基础题
- 4000 网络流最大流--Power Network
- POJ 1459 Power Network 网络流基础题
- POJ 1459 Power Network (最大流, 网络流, EdmondsKarp算法求解最大流)
- POJ - 1459 Power Network(网络流-最大流)
- poj 1459 Power Network 网络流
- POJ 1459 Power Network——(网络流入门)
- Power Network(网络流最大流 & dinic算法 + 优化)
- POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)
- Power Network_网络流基础题_2018_3_17
- POJ-1459-Power Network(网络流 EK)
- POJ 1459 PowerNetwork 多源点网络流入门(EK算法求最大流)
- poj 1459 Power Network 网络流 ek算法