POJ-3469 Dual Core CPU 最小割

  题目链接: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 }
posted @ 2012-12-03 17:17  zhsl  阅读(422)  评论(0编辑  收藏  举报