POJ 3469 【最小割】.cpp
题意:
给出一些部件和他们单个在不同CPU里工作时需要的消耗值
以及在两个不同CPU里工作的部件共同工作时的消耗值..
问怎么分配可以使总的消耗值最少..
输入:
n m 表示有n个部件 m个工作连通消耗值
接下来n行每行给出 a b 表示在第一台CPU消耗a 在第二台CPU消耗b
然后m行给出a b w 表示a部件和b部件在不同的机子连通工作需要消耗w..
输出:
最少总消耗
思路:
最大流 = 最小割
Tips:
加入边的时候应该同时加入反向边
还有因为多加了超级源点和超级汇点 所以边也增多了~
要相应增加边的条数..
Code:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <cstring> 3 #include <stdlib.h> 4 using namespace std; 5 #define clr(x) memset(x, 0xff, sizeof(x)) 6 #define min(a,b)(a)<(b)?(a):(b) 7 const int INF=0x1f1f1f1f; 8 const int maxn=20010; 9 const int maxm=4000010; 10 struct node 11 { 12 int c,next,to; 13 }e[maxm]; 14 int tot; 15 int head[maxn]; 16 17 void add(int s,int u,int flow) 18 { 19 e[tot].to=u; 20 e[tot].c=flow; 21 e[tot].next=head[s]; 22 head[s]=tot++; 23 } 24 25 int max_flow(int st,int end,int n) 26 { 27 int numh[maxn],h[maxn],curedge[maxn],pre[maxn]; 28 int cur_flow,maxflow=0,u,tmp,neck,i; 29 memset(h,0,sizeof(h)); 30 memset(numh,0,sizeof(numh)); 31 memset(pre,0xff,sizeof(pre)); 32 for(i=0;i< n;i++) 33 curedge[i]=head[i]; 34 35 numh[0]=n; 36 u=st; 37 while(h[st]<n) 38 { 39 if(u==end) 40 { 41 cur_flow=INF; 42 for(i=st;i!=end;i=e[curedge[i]].to) 43 if(cur_flow>e[curedge[i]].c) 44 { 45 neck=i; 46 cur_flow=e[curedge[i]].c; 47 } 48 for(i=st;i!=end;i=e[curedge[i]].to) 49 { 50 tmp=curedge[i]; 51 e[tmp].c-=cur_flow; 52 e[tmp^1].c+=cur_flow; 53 } 54 maxflow+=cur_flow; 55 u=neck; 56 } 57 for(i=curedge[u];i!=-1;i=e[i].next) 58 if(e[i].c&&h[u]==h[e[i].to]+1) 59 break; 60 if(i!=-1) 61 { 62 curedge[u]=i; 63 pre[e[i].to]=u; 64 u=e[i].to; 65 } 66 else 67 { 68 if(--numh[h[u]]==0) break; 69 curedge[u]=head[u]; 70 for(tmp=n,i=head[u];i!=-1;i=e[i].next) 71 if(e[i].c) 72 tmp=min(tmp,h[e[i].to]); 73 h[u]=tmp+1; 74 ++numh[h[u]]; 75 if(u!=st) 76 u=pre[u]; 77 } 78 } 79 return maxflow; 80 } 81 82 int main() 83 { 84 int i, j, k; 85 int a, b, w; 86 int n, m; 87 while(scanf("%d %d", &n, &m) != EOF) 88 { 89 tot = 0; 90 clr(head); 91 92 for(i = 1; i <= n; ++i) { 93 scanf("%d %d", &a, &b); 94 add(0, i, a); 95 add(i, 0, 0); 96 add(i, n+1, b); 97 add(n+1, i, b); 98 } 99 100 while(m--) { 101 scanf("%d %d %d", &a, &b, &w); 102 add(a, b, w); 103 add(b, a, w); 104 } 105 106 int ans = max_flow(0, n+1, n+2); 107 printf("%d\n", ans); 108 } 109 return 0; 110 }