Power Network POJ - 1459(多源点多汇点)

xiaoxiao2021-02-27  321

题意:和普通的求最大流没什么区别,就是多源点多汇点,只要建立一个超级源点和汇点就行了。

#include <queue> #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 10000+5; const int INF = 0x3f3f3f3f; struct Edge { int from,to,cap,flow; }; vector<Edge> edges;//e和e^1互为反向弧 vector<int> G[maxn];//图的邻接表,表示节点i的第j条边在边数组里的编号 int d[maxn];// 用来记录标号距离(层次图使用) int cur[maxn];//当前弧的下标 bool vst[maxn]; int n, m, s, t;//节点数,边数,super源点编号,super汇点编号 int nt,ns; // 源点个数,汇点个数 void Init() //清空图 { for(int i=0; i<maxn; i++) { G[i].clear(); } edges.clear(); } void AddEdge(int from,int to,int cap) //加边时考虑到流量推回,再建立一条反向的边 { edges.push_back((Edge) { from,to,cap,0 }); edges.push_back((Edge) { to,from,0,0 }); int sz=edges.size(); G[from].push_back(sz-2); G[to].push_back(sz-1); } bool BFS() //BFS建立层次图 { memset(vst,false,sizeof(vst)); queue<int> Q; Q.push(s); d[s]=0; vst[s]= true; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int i=0; i<G[u].size(); i++) { Edge& e = edges[G[u][i]]; if(!vst[e.to]&&e.cap>e.flow) //这里很关键,容量和流量的关系判断能否前进到汇点,如果没有増广路连接汇点的话,说明已经找到了最大流量了。 { d[e.to]=d[u]+1; vst[e.to]=true; Q.push(e.to); } } } return vst[t]; } int DFS(int u,int a) //传入的u为当前节点,a为到目前为止所有弧的最小残量 { if(u==t||a==0) return a; int f,flow= 0; for(int i=cur[u]; i<G[u].size(); i++) //从上次考虑的弧开始避免重复计算 { Edge& e = edges[G[u][i]]; if(d[e.to]==d[u]+1&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0) { e.flow+=f; edges[G[u][i]^1].flow -= f; flow+=f; a-=f; if(a==0) break; } } return flow; } int Maxflow() { int flow = 0; while(BFS())//每次都寻找当前层的増广 { memset(cur,0,sizeof(cur)); flow += DFS(s,INF); } return flow; } int main() { while(cin >> n >> ns >> nt >> m) { Init(); int from,to,cap; char ch; for(int i=0; i<m; i++) { cin >> ch >> from >> ch >> to >>ch >> cap ; from+=2; to+=2; AddEdge(from,to,cap); } int pow,number; for(int i=0; i<ns; i++) { cin >> ch >> number >> ch >> pow ; number+=2; AddEdge(1,number,pow); } for(int i=0; i<nt; i++) { cin >> ch >> number >> ch >> pow ; number+=2; AddEdge(number,n+2,pow); } s=1; t=n+2; cout << Maxflow() <<endl; } return 0; }

转载请注明原文地址: https://www.6miu.com/read-2224.html

最新回复(0)