题目描述:
由于越来越多的计算机配置了双核CPU,TinySoft公司的首席技术官员,SetagLilb,决定升
级他们的产品-SWODNIW。
SWODNIW包含了N个模块,每个模块必须运行在某个CPU中。每个模块在每个CPU中
运行的耗费已经被估算出来了,设为Ai和Bi。同时,M对模块之间需要共享数据,如果他们运行
在同一个CPU中,共享数据的耗费可以忽略不计,否则,还需要额外的费用。你必须很好地安排
这N个模块,使得总耗费最小。
思路: 如果将两个CPU分别视为源点和汇点、模块视为顶点,则可以按照以下方式构图:对于第i
个模块在每个CPU中的耗费Ai和Bi, 从源点向顶点i连接一条容量为Ai的弧、从顶点i向汇点
连接一条容量为Bi的弧;对于a模块与b模块在不同CPU中运行造成的额外耗费w,顶点a
与顶点b连接一条容量为w的弧。此时每个顶点(模块)都和源点及汇点(两个CPU)相连,即
每个模块都可以在任意一个CPU中运行
不难了解到,对于图中的任意一个割,源点与汇点必不连通。因此每个顶点(模块)都不可
能同时和源点及汇点(两个CPU)相连,即每个模块只在同一个CPU中运行。此时耗费即为割
的容量。很显然,当割的容量取得最小值时,总耗费最小。故题目转化为求最小割的容量。
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 20010
#define maxm 1000000
#define LL long long
struct Eg{
int to;
int next;
int f;
}E[maxm];
int V[maxn],num;
int N,M;
void add(int u,int v,int c){
E[num].to=v;
E[num].f=c;
E[num].next=V[u];
V[u]=num++;
E[num].to=u;
E[num].f=0;
E[num].next=V[v];
V[v]=num++;
}
int level[maxn];
int qu[maxn];
bool BFS(int s,int t){
int i,iq=0;
// memset(level,0,sizeof(level));
for(i=0;i<=t;i++) level[i]=0;
//queue<int> Q;
int u,v,e;
qu[iq++]=s;// Q.push(s);
level[s]=1;
// while(!Q.empty()){
for(i=0;i<iq;i++){
u=qu[i];//Q.front();
//Q.pop();
if(u==t) return true;
for(e=V[u];e!=-1;e=E[e].next){
v=E[e].to;
if(!level[v]&&E[e].f>0)
{
level[v]=level[u]+1;
qu[iq++]=v;// Q.push(v);
}
}
}
return false;
}
int cur[maxn];
int dfs(int u,int maxf,int t){
if(u==t||maxf==0) return maxf;
int ret=0,f,e,v;
for(e=cur[u];e!=-1;e=E[e].next){// 当前弧优化
v=E[e].to;
if(E[e].f>0&&level[u]+1==level[v]){
f= dfs(v,min(maxf,E[e].f),t);
E[e].f-=f;
E[e^1].f+=f;
maxf-=f;
ret+=f;
cur[u]=e;
if(maxf==0) break;
}
}
return ret;
}
int Dinic(int s,int t){
int flow=0;
while(BFS(s,t)){
for(int i=0;i<=t;i++)
cur[i]=V[i];
flow+=dfs(s,MOD,t);
}
return flow;
}
int main(){
int i;
int a,b,w;
while(scanf("%d %d",&N,&M)!=EOF){
for(i=0;i<=N+1;i++)V[i]=-1;
num=0;
for(i=1;i<=N;i++){
scanf("%d %d",&a,&b);
add(0,i,a);
add(i,N+1,b);
}
while(M--){
scanf("%d %d %d",&a,&b,&w);
add(a,b,w);
add(b,a,w);
}
printf("%d
",Dinic(0,N+1));
}
return 0;
}