POJ 1459 Power Network 最大流(Edmonds_Karp算法)
题目链接: http://poj.org/problem?id=1459
因为发电站有多个,所以需要一个超级源点,消费者有多个,需要一个超级汇点,这样超级源点到发电站的权值就是发电站的容量,也就是题目中的pmax,消费者到超级汇点的权值就是消费者的容量,也就是题目中的cmax。初学网络流,第一眼看到这个题还以为应该先做一遍EK算法,然后减去max(p-pmax, c-cmax)呢。。没想到这个题的难点就是建图而已。。
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <algorithm> 5 using namespace std; 6 7 const int INF = 0x3f3f3f3f; 8 int cap[110][110], flow[110][110], res[110], pre[110]; 9 int start, end; 10 int n_node, n_power, n_consumer, n_line; 11 queue<int>que; 12 13 int Edmonds_Karp() 14 { 15 while(!que.empty())que.pop(); 16 int flow_sum = 0; 17 while(true) 18 { 19 memset(res, 0, sizeof(res)); 20 res[start] = INF; 21 que.push(start); 22 while(!que.empty()) 23 { 24 int u = que.front(); 25 que.pop(); 26 for(int v = 0; v < n_node+2; v++) 27 { 28 if(!res[v] && cap[u][v] > flow[u][v]) 29 { 30 pre[v] = u; 31 que.push(v); 32 res[v] = min(res[u], cap[u][v] - flow[u][v]); 33 } 34 } 35 } 36 if(res[end] == 0)break; 37 for(int u = end; u != start; u = pre[u]) 38 { 39 flow[pre[u]][u] += res[end]; 40 flow[u][pre[u]] -= res[end]; 41 } 42 flow_sum += res[end]; 43 } 44 return flow_sum; 45 } 46 47 int main() 48 { 49 char fuck_space[110];//18禁。。 50 while(scanf("%d %d %d %d", &n_node, &n_power, &n_consumer, &n_line) != EOF) 51 { 52 int u, v, w; 53 memset(cap, 0, sizeof(cap)); 54 memset(flow, 0, sizeof(flow)); 55 start = n_node; 56 end = n_node+1; 57 for(int i = 0; i < n_line; i++) 58 { 59 scanf("%s", fuck_space); 60 sscanf(fuck_space, "(%d,%d)%d", &u, &v, &w); 61 cap[u][v] += w; 62 } 63 for(int i = 0; i < n_power; i++) 64 { 65 scanf("%s", fuck_space); 66 sscanf(fuck_space, "(%d)%d", &u, &w); 67 cap[start][u] += w; 68 } 69 for(int i = 0; i < n_consumer; i++) 70 { 71 scanf("%s", fuck_space); 72 sscanf(fuck_space, "(%d)%d", &u, &w); 73 cap[u][end] += w; 74 } 75 printf("%d\n", Edmonds_Karp()); 76 } 77 return 0; 78 }