poj 1459 Power Network(网络流)

2019-04-14 12:24发布

题意: n个点,其中np个点最多能发p[i]电,nc个点最多消耗c[i]电,有m条传输路线,最多能传输w[i]电,问最多总共能消耗多少电。
解题思路: 网络流经典题。 没学网络流前想了下枚举边不就做出来了嘛,但是仔细一想,发现如果随意枚举的话,会出现某些发电的点不能被充分利用的情况,如果调换下顺序,则能得到充分利用,所以感觉需要解决的就是一个顺序问题。 然后学了Edmonds-Karp 算法后,发现ek算法其实就是加了回边,每次去走回边其实相当于撤销了原来被走过的正边,然后这样每次bfs都这样去走,直到走不到汇点为止,就能保证正确性了。
感觉这个算法巧的地方就在于走回边了。
这个题dfs的话会t,改成bfs就过。
代码: #include #include #include #include #define ps push_back using namespace std; const int maxn=120; const int inf=1e9; struct node{ int from; int cap; int x; }que[maxn*maxn]; int a[maxn][maxn]; int n, m, np, cp, s, t; int used[maxn]; /* int dfs(int u, int t, int cap) { if(u==t)return cap; int res; used[u]=1; for(int i=0; i<=t; i++) { if(used[i]==0 && a[u][i]>0) { res=dfs(i, t, min(cap, a[u][i])); if(res>0) { a[u][i]-=res; a[i][u]+=res; return res; } } } return 0; } */ int bfs(int s, int t) { int head, tail, x; head=tail=0; que[tail].from=-1, que[tail].x=s, que[tail++].cap=inf; used[s]=1; while(head0) { used[i]=1; que[tail].from=head, que[tail].x=i, que[tail++].cap=min(que[head].cap, a[x][i]); } } head++; } if(x==t) { int mi=que[head].cap; while(que[head].from!=-1) { a[que[que[head].from].x][que[head].x]-=mi; a[que[head].x][que[que[head].from].x]+=mi; head=que[head].from; } return mi; } return 0; } int f(int s, int t) { int flow=0; while(1) { memset(used, 0, sizeof used); int res=bfs(s, t); if(res==0)return flow; flow+=res; } } int main() { ios::sync_with_stdio(false); cin.tie(0); string in; stringstream ss; char e; while(cin>>n>>np>>cp>>m) { memset(a, 0, sizeof a); int u, v, w; s=n, t=n+1; while(m--) { cin>>e>>u>>e>>v>>e>>w; a[u][v]=w; } while(np--) { cin>>e>>v>>e>>w; a[s][v]=w; } while(cp--) { cin>>e>>v>>e>>w; a[v][t]=w; } cout<