POJ 1459 Power Network
这题是一个标准的最大流问题。
题目大意是:有n个点,其中nc个点是发电站,有np个点是用户,其他的是中转站,求最大流。
问题中存在着多源点和多汇点,我们可以把这些源点和汇点当作中转站,在虚拟一个超级源点和超级汇点,EK算法上模版,G++编译器1391MS。
下面是代码:
#include <iostream> #include <string.h> #include <queue> using namespace std; const int inf = 1<<30; const int M =105; int map1[M][M],pre[M],vis[M],n; int EK() { int i,ans=0,now,min1; queue <int> q; while(1) //每循环一次找一次增广路 { memset(pre,-1,sizeof(pre)); memset(vis,0,sizeof(vis)); while(!q.empty()) { q.pop(); } q.push(0); vis[0]=1; while(!q.empty()) { now=q.front(); q.pop(); if(now==n+1) //已经搜索到超级汇点 跳出循环 { break; } for(i=0;i<=n+1;i++) { if(!vis[i]&&map1[now][i]>0)//如果节点i没被搜索过且节点now到节点i残余流量大于0 { pre[i]=now; //记录i的前驱节点是now vis[i]=1; //标记i点已经被访问过 q.push(i); //把i点放入队列进行下一次BFS } } } if(!vis[n+1]) { break; //如果BFS完毕没有搜到到节点n+1的增广路,就已经找到最大流 跳出 } min1=inf; for(i=n+1;i!=0;i=pre[i]) { if(map1[pre[i]][i]<min1) //寻找整个增广路上的残余流量的最小值,此为整个增广路的流量 { min1=map1[pre[i]][i]; } } ans+=min1; for(i=n+1;i!=0;i=pre[i]) { map1[pre[i]][i]-=min1;//残余流量减少 map1[i][pre[i]]+=min1;//已使用流量增加 } } return ans; } int main() { int np,nc,m,i; while(cin >> n >> np >> nc >> m) { char s; int u,v,w; memset(map1,0,sizeof(map1)); for(i=0;i<m;i++) { cin >> s >> u >> s >> v >> s >> w; if(u!=v) { map1[u+1][v+1]=w; } } for(i=0;i<np;i++) { cin >> s >> v >> s >> w ; map1[0][v+1]=w; } for(i=0;i<nc;i++) { cin >> s >> u >> s>> w ; map1[u+1][n+1]=w; } cout << EK() << endl; } return 0; }