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:

View Code
  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 }

 

题目链接:http://poj.org/problem?id=3469

posted @ 2012-09-29 21:05  Griselda.  阅读(160)  评论(0编辑  收藏  举报