题目链接:http://poj.org/problem?id=3469
题目的意思是这样的:有n个任务要处理,现在有一个双核心的CPU,每个任务可以在其中一个核心被完成且需要一定代价,其代价分别为Ai和Bi,如果某些任务在不同的核心上处理,可能需会要需要进行数据交换,即第a个任务和第b个任务为w(a,b,w)。现在要你分配这n个任务,使得所需的代价最小。
开始看到这个题目的时候以为是最小费用流,于是建图建了半天,也没建出来,后来看了下Discuss,才发现是最小割!关键还是在建图上:把每个任务看做点,加源点s和汇点t,从s向每个任务点建立单向边,容量为Ai。从每个任务点向t建里单向边,容量为Bi。然后每个任点之间建立双向边,即(a,b,w)。然后就是最小割模型了,因为求出的最小割如果没有选择连向s的边,要么会选择连向t的边。
1 //STATUS:G++_AC_3891MS_8528KB 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<math.h> 6 #include<iostream> 7 #include<string> 8 #include<algorithm> 9 #include<vector> 10 #include<queue> 11 #include<stack> 12 #include<map> 13 using namespace std; 14 #define LL long long 15 #define Max(a,b) ((a)>(b)?(a):(b)) 16 #define Min(a,b) ((a)<(b)?(a):(b)) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 const int MAX=20010,INF=0x3f3f3f3f; 21 22 struct Edge{ 23 int u,v,cap; 24 }e[MAX*30]; 25 26 int first[MAX],next[MAX*30],d[MAX],cur[MAX]; 27 int n,m,s,t,mm; 28 29 void adde1(int a,int b,int val) 30 { 31 e[mm].u=a;e[mm].v=b; 32 e[mm].cap=val; 33 next[mm]=first[a];first[a]=mm++; 34 e[mm].u=b;e[mm].v=a; 35 e[mm].cap=0; 36 next[mm]=first[b];first[b]=mm++; 37 } 38 39 void adde2(int a,int b,int val) 40 { 41 e[mm].u=a;e[mm].v=b; 42 e[mm].cap=val; 43 next[mm]=first[a];first[a]=mm++; 44 e[mm].u=b;e[mm].v=a; 45 e[mm].cap=val; 46 next[mm]=first[b];first[b]=mm++; 47 } 48 49 int bfs() 50 { 51 int x,i,j; 52 queue<int> q; 53 mem(d,0); 54 q.push(s); 55 d[s]=1; 56 while(!q.empty()){ 57 x=q.front();q.pop(); 58 for(i=first[x];i!=-1;i=next[i]){ 59 if(e[i].cap && !d[e[i].v]){ 60 d[e[i].v]=d[x]+1; 61 q.push(e[i].v); 62 } 63 } 64 } 65 return d[t]; 66 } 67 68 int dfs(int x,int a) 69 { 70 if(x==t || a==0)return a; 71 int f,flow=0; 72 for(int& i=cur[x];i!=-1;i=next[i]){ 73 if(d[x]+1==d[e[i].v] && (f=dfs(e[i].v,Min(a,e[i].cap)))){ 74 e[i].cap-=f; 75 e[i^1].cap+=f; 76 flow+=f; 77 a-=f; 78 if(!a)break; 79 } 80 } 81 return flow; 82 } 83 84 int dinic() 85 { 86 int i,flow=0; 87 while(bfs()){ 88 for(i=0;i<=t;i++)cur[i]=first[i]; 89 flow+=dfs(s,INF); 90 } 91 return flow; 92 } 93 94 int main() 95 { 96 // freopen("in.txt","r",stdin); 97 int i,a,b,val; 98 while(~scanf("%d%d",&n,&m)) 99 { 100 mm=0; 101 mem(first,-1); 102 s=0,t=n+1; 103 for(i=1;i<=n;i++){ 104 scanf("%d%d",&a,&b); 105 adde1(s,i,a); 106 adde1(i,t,b); 107 } 108 for(i=0;i<m;i++){ 109 scanf("%d%d%d",&a,&b,&val); 110 adde2(a,b,val); 111 } 112 113 printf("%d\n",dinic()); 114 } 115 return 0; 116 }