http://poj.org/problem?id=1459
题意:有np个发电站,nc个消费者,m条边,边有容量限制,发电站有产能上限,消费者有需求上限问最大流量。
思路:S和发电站相连,边权是产能上限,消费者和T相连,边权是需求上限,边的话就按题意加就好了。难点更觉得在于输入。。加个空格。。边数组要*2,因为有反向边。
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <queue> 8 #include <vector> 9 #include <map> 10 #include <set> 11 using namespace std; 12 #define INF 0x3f3f3f3f 13 #define N 110 14 typedef long long LL; 15 struct Edge { 16 int v, cap, nxt; 17 Edge () {} 18 Edge (int v, int cap, int nxt) : v(v), cap(cap), nxt(nxt) {} 19 }edge[N*N*2]; 20 int tot, cur[N], dis[N], pre[N], head[N], gap[N], S, T; 21 22 void Add(int u, int v, int cap) { 23 edge[tot] = Edge(v, cap, head[u]); head[u] = tot++; 24 edge[tot] = Edge(u, 0, head[v]); head[v] = tot++; 25 } 26 27 void BFS() { 28 queue<int> que; 29 while(!que.empty()) que.pop(); 30 memset(dis, -1, sizeof(dis)); 31 memset(gap, 0, sizeof(gap)); 32 dis[T] = 0; gap[0]++; que.push(T); 33 while(!que.empty()) { 34 int u = que.front(); que.pop(); 35 for(int i = head[u]; ~i; i = edge[i].nxt) { 36 int v = edge[i].v; 37 if(dis[v] == -1) continue; 38 dis[v] = dis[u] + 1; 39 gap[dis[v]]++; 40 que.push(v); 41 } 42 } 43 } 44 45 int ISAP(int n) { 46 memcpy(cur, head, sizeof(cur)); 47 BFS(); 48 int u = pre[S] = S, ans = 0, i; 49 while(dis[S] < n) { 50 if(u == T) { 51 int flow = INF, index; 52 for(int i = S; i != T; i = edge[cur[i]].v) { 53 Edge& e = edge[cur[i]]; 54 if(e.cap < flow) { 55 flow = e.cap; index = i; 56 } 57 } 58 for(int i = S; i != T; i = edge[cur[i]].v) { 59 edge[cur[i]].cap -= flow; 60 edge[cur[i]^1].cap += flow; 61 } 62 ans += flow; u = index; 63 } 64 for(i = cur[u]; ~i; i = edge[i].nxt) 65 if(dis[edge[i].v] == dis[u] - 1 && edge[i].cap > 0) 66 break; 67 if(~i) { 68 cur[u] = i; 69 pre[edge[i].v] = u; 70 u = edge[i].v; 71 } else { 72 int md = n; 73 if(--gap[dis[u]] == 0) break; 74 for(int i = head[u]; ~i; i = edge[i].nxt) { 75 if(md > dis[edge[i].v] && edge[i].cap > 0) { 76 md = dis[edge[i].v]; cur[u] = i; 77 } 78 } 79 ++gap[dis[u] = md + 1]; 80 u = pre[u]; 81 } 82 } 83 return ans; 84 } 85 86 int main() { 87 int n, nc, np, m; 88 while(~scanf("%d%d%d%d", &n, &np, &nc, &m)) { 89 tot = 0; memset(head, -1, sizeof(head)); 90 S = n, T = n + 1; 91 int a, b, c; 92 for(int i = 1; i <= m; i++) { 93 scanf(" (%d,%d)%d", &a, &b, &c); 94 Add(a, b, c); 95 } 96 for(int i = 1; i <= np; i++) { 97 scanf(" (%d)%d", &a, &b); 98 Add(S, a, b); 99 } 100 for(int i = 1; i <= nc; i++) { 101 scanf(" (%d)%d", &a, &b); 102 Add(a, T, b); 103 } 104 printf("%d\n", ISAP(T+1)); 105 } 106 return 0; 107 }
时间: 2024-12-28 00:44:39