最小割是等于最大流的。
割:将vs与vt分成两个集合的那些前向弧。
最小割:容量最小的割。
#include<stdio.h>
#include<string.h>
#define MX 10000000
int n,m,numb,d[30010],queue[1000000],next[900010],list[30010];
struct edge{
int u,v,flow;
}eg[900000];
void add(int u,int v,int flow){
eg[numb].u=u;eg[numb].v=v;eg[numb].flow=flow;next[numb]=list[u];list[u]=numb++;
eg[numb].u=v;eg[numb].v=u;eg[numb].flow=flow;next[numb]=list[v];list[v]=numb++;
}
int min(int a,int b){
return a<b?a:b;
}
bool bfs(){
int qs=0,qe=1;
queue[qs]=0;
memset(d,-1,sizeof(d));
d[0]=0;
while(qs<qe){
int v=queue[qs++];
for(int i=list[v];i!=-1;i=next[i]){
if(eg[i].flow&&d[eg[i].v]==-1){
queue[qe++]=eg[i].v;
d[eg[i].v]=d[v]+1;
}
}
}
if(d[n+1]==-1)return false;
return true;
}
int dfs(int sta,int sum){
if(sta==n+1){
return sum;
}
int sumcy=sum;
for(int i=list[sta];i!=-1;i=next[i]){
if(d[eg[i].v]==d[sta]+1&&eg[i].flow){
int t=dfs(eg[i].v,min(sum,eg[i].flow));
eg[i].flow-=t;
eg[i^1].flow+=t;
sum-=t;
}
}
return sumcy-sum;
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
numb=0;
memset(list,-1,sizeof(list));
for(int i=1;i<=n;i++){
int ai,bi;
scanf("%d%d",&ai,&bi);
add(0,i,ai);
add(i,n+1,bi);
}
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
}
int ans=0;
while(bfs()){
ans+=dfs(0,MX);
}
printf("%d\n",ans);
}
return 0;
}