Sample Input
3 1 1 10 2 10 10 3 2 3 1000
Sample Output
13
最小割,把模块看做点,建源点s和汇点t,以下(a,b,c)表示从a向b连一条容量为c的边
记在核A上的执行的模块集合为S,在核B上的执行的模块集合为T,花费的总和为
对于,这是该模块在A核花费的费用,连一条(i,t,Ai)的边
对于,这是该模块在A核花费的费用,连一条(s,i,Bi)的边
对于,这是ai模块在A核,bi模块在B核的费用,连一条(ai,bi,wi)的边
对于,这是ai模块在B核,bi模块在A核的费用,连一条(bi,ai,wi)的边
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int INF=1999999999; int r,c,d;int n,m; struct data{ int next,to,cap; }g[1000101]; int iter[20101],h[20101],level[20101],k=1,head,tail,q[20101]; inline int read(){ int x; bool f; char c; for (f=0; (c=getchar())<'0'||c>'9'; f=c=='-'); for (x=c-'0'; (c=getchar())>='0'&&c<='9'; x=(x<<3)+(x<<1)+c-'0'); return f?-x:x; } void add(int from,int to,int cap) { g[++k].next=h[from];h[from]=k;g[k].to=to;g[k].cap=cap; g[++k].next=h[to];h[to]=k;g[k].to=from;g[k].cap=0; } void bfs(int s) { memset(level,0,sizeof(level)); head=tail=0;q[tail++]=s;level[s]=1; while(head!=tail) { int u=q[head++]; for(int i=h[u];i;i=g[i].next) { if(!level[g[i].to]&&g[i].cap) { level[g[i].to]=level[u]+1;q[tail++]=g[i].to; } } } } int dfs(int u,int t,int f) { if(u==t)return f; int used=0,w; for(int &i=iter[u];i;i=g[i].next) { if(g[i].cap&&level[g[i].to]==level[u]+1) { w=f-used;w=dfs(g[i].to,t,min(w,g[i].cap)); if(w) { g[i].cap-=w;g[i^1].cap+=w;used+=w;if(used==f)return f; } } } return used; } int dinic(int s,int t) { int flow=0; for(;;) { for(int i=0;i<=n+1;i++)iter[i]=h[i]; bfs(s);if(!level[t])return flow; flow+=dfs(s,t,INF); } } int main() { n=read();m=read();int S=0,T=n+1; for(int i=1;i<=n;i++) { int a=read(),b=read(); add(S,i,b);add(i,T,a); } for(int i=1;i<=m;i++) { int a=read(),b=read(),w=read(); add(a,b,w);add(b,a,w); } printf("%d",dinic(S,T)); return 0; }