题目链接: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 }