標籤:
第一道網路流題,紀念下~~~
題目連結:
http://poj.org/problem?id=1459
題目大意:
一個電力網路包含很多節點(發電站、消費者以及中轉站)和電力傳輸線。所有發電站不消耗電力,
所有消費者不產生電力,所有中轉站不產生也不消耗電力。在網路中,任意兩點u和v之間最多隻
有一條傳輸線的存在,且能夠從u望v傳輸最多w單位容量。計算整個網路的最大電力消耗。
思路:
一道非常基礎、非常典型的網路流題目。每個發電站當做一個源點,每個消費者當做一個匯點。但
是這樣子並不適合任何一種求網路最大流演算法。那麼現在設定一個超級源點,連向所有發電站,容
量為發電站的點容量。再來設定一個超級匯點,讓所有的消費者連向超級匯點,邊容量為消費者的
點容量。下面就可以通過最大流演算法來解決問題了。這裡用Edmond-Karp演算法來做。
AC代碼:
#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN = 220;int Map[MAXN][MAXN],pre[MAXN];int N,NP,NC,M;bool EkBFS(int start,int end){ queue<int> Q; bool vis[MAXN]; memset(vis,false,sizeof(vis)); memset(pre,-1,sizeof(pre)); Q.push(start); vis[start] = true; while( !Q.empty() ) { int u = Q.front(); if(u == end) return true; Q.pop(); for(int i = 0; i <= N+1; ++i) { if(Map[u][i] && !vis[i]) { vis[i] = true; pre[i] = u; Q.push(i); } } } return false;}int EkMaxFlow(int start,int end){ int v,Ans = 0,MinN; while(EkBFS(start,end)) { MinN = 0xffffff0; v = end; while( pre[v] != -1) { MinN = min(MinN,Map[pre[v]][v]); v = pre[v]; } Ans += MinN; v = end; while( pre[v] != -1) { Map[pre[v]][v] -= MinN; Map[v][pre[v]] += MinN; v = pre[v]; } } return Ans;}int main(){ char ch; int u,v,w; while(~scanf("%d %d %d %d ",&N,&NP,&NC,&M)) { memset(Map,0,sizeof(Map)); for(int i = 0; i < M; ++i) { while( (ch = getchar())!='(' ); scanf("%d",&u); getchar(); scanf("%d",&v); getchar(); scanf("%d",&w); Map[u][v] = w; } for(int i = 0; i < NP+NC; ++i) { while( (ch = getchar())!='(' ); scanf("%d",&u); getchar(); scanf("%d",&w); if(i < NP) Map[N][u] = w; else Map[u][N+1] = w; } printf("%d\n",EkMaxFlow(N,N+1)); } return 0;}
POJ1459 Power Network【最大流】【Edmond-Karp】