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 }

你可能感兴趣的:(core)