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

sollution:把两个CPU视为源点和汇点、模块视为顶点。源点到第i个模块连容量为Ai的边,第i个模块到汇点连容量为Bi的边,然后两个特殊模块连双向边。

根据最大流最小割定理,求最大流。

代码:

  1 #include <algorithm>
  2  #include <iostream>
  3  #include <cstring>
  4  #include <cstdio>
  5  #include <queue>
  6  using namespace std;
  7  const int maxn=101050;
  8  const int maxm=3000000;
  9  const int oo=1<<30;
 10  int idx,N,F,D;
 11  int cur[maxn],pre[maxn];
 12  int dis[maxn],gap[maxn];
 13  int aug[maxn],head[maxn];
 14  struct Node
 15  {
 16      int u, v, w;
 17      int next;
 18  }edge[maxm];
 19  void addEdge(int u, int v, int w)
 20  {
 21      edge[idx].u=u;
 22      edge[idx].v=v;
 23      edge[idx].w=w;
 24      edge[idx].next=head[u];
 25      head[u]=idx++;
 26      edge[idx].u=v;
 27      edge[idx].v=u;
 28      edge[idx].w=0;
 29      edge[idx].next=head[v];
 30      head[v]=idx++;
 31  }
 32  int SAP(int s,int e,int n)
 33  {
 34      int max_flow=0,v,u=s;
 35      int id,mindis;
 36      aug[s]=oo;
 37      pre[s]=-1;
 38      memset(dis,0,sizeof(dis));
 39      memset(gap,0,sizeof(gap));
 40      gap[0] = n;
 41      for (int i=0;i<=n;i++)
 42      {
 43          cur[i]=head[i];
 44      }
 45      while(dis[s]<n)
 46      {
 47          bool flag=false;
 48          if(u==e)
 49          {
 50              max_flow+=aug[e];
 51              for (v=pre[e];v!=-1;v=pre[v])
 52              {
 53                  id = cur[v];
 54                  edge[id].w-=aug[e];
 55                  edge[id^1].w+=aug[e];
 56                  aug[v]-=aug[e];
 57                  if (edge[id].w==0)
 58                  u=v;
 59              }
 60          }
 61          for(id=cur[u];id!=-1;id=edge[id].next)
 62          {
 63              v=edge[id].v;
 64              if(edge[id].w>0&&dis[u]==dis[v]+1)
 65              {
 66                  flag=true;
 67                  pre[v]=u;
 68                  cur[u]=id;
 69                  aug[v]=min(aug[u], edge[id].w);
 70                  u=v;
 71                  break;
 72              }
 73          }
 74          if (flag==false)
 75          {
 76              if(--gap[dis[u]]==0)
 77              break;
 78              mindis=n;
 79              cur[u]=head[u];
 80              for(id=head[u];id!=-1;id=edge[id].next)
 81              {
 82                  v=edge[id].v;
 83                  if(edge[id].w>0&&dis[v]<mindis)
 84                  {
 85                      mindis=dis[v];
 86                      cur[u]=id;
 87                  }
 88              }
 89              dis[u]=mindis+1;
 90              gap[dis[u]]++;
 91              if(u!=s)
 92              u=pre[u];
 93          }
 94      }
 95      return max_flow;
 96  }
 97 int main()
 98 {
 99     int n,m,i,j,a,b,c;
100     scanf("%d%d",&n,&m);
101     int source=0,sink=n+1;
102     memset(head,-1,sizeof(head));
103     idx=0;
104     for(i=1;i<=n;i++)
105     {
106         scanf("%d%d",&a,&b);
107         addEdge(0,i,a);
108         addEdge(i,n+1,b);
109     }
110     while(m--)
111     {
112         scanf("%d%d%d",&a,&b,&c);
113         addEdge(a,b,c);
114         addEdge(b,a,c);
115     }
116     printf("%d\n",SAP(0,n+1,n+2));
117     return 0;
118  }
posted on 2012-10-10 17:31  pony1993  阅读(257)  评论(0编辑  收藏  举报

View My Stats