/*这个题目的构图还是不错的,关键是最大流最小割定理的理解程度,算法用的是ISAP,效率还不错。 需要注意的是比如这句话 edge[index].pair = ++index,不同的编译器对这句话的翻译是不一样的, 主要是对++index的处理,有的是先对++index处理:++index,edge[index].pair = index,而有的不是, 可能翻译成:edge[index].pair = index + 1;++index,就是在这个地方WA了好几次,这种错误真是太难检查 了、、、、归根结蒂还是自己对语言了解部透彻,编码习惯不太好。。。。*/
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
#define MAXN 30020
#define MAXE 2000000
#define INF 0x3fffffff
int ne,nv,index,s,t,net[MAXN];
struct Edge{
int next,pair;
int v,cap,flow;
}edge[MAXE];
void add(const int& u,const int& v,const int& val)
{
edge[index].next = net[u];
net[u] = index;
edge[index].v = v;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index+1;
++index;
edge[index].next = net[v];
net[v] = index;
edge[index].v = u;
edge[index].cap = 0;
edge[index].flow = 0;
edge[index].pair = index - 1;
++index;
}
int ISAP()
{
long numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
long cur_flow,max_flow,u,tmp,neck,i;
memset(dist,0,sizeof(dist));
memset(numb,0,sizeof(numb));
for(i = 1 ; i <= nv ; ++i)
curedge[i] = net[i];
numb[nv] = nv;
max_flow = 0;
u = s;
while(dist[s] < nv)
{
/* first , check if has augmemt flow */
if(u == t)
{
cur_flow = INF;
for(i = s; i != t;i = edge[curedge[i]].v)
{
if(cur_flow > edge[curedge[i]].cap)
{
neck = i;
cur_flow = edge[curedge[i]].cap;
}
}
for(i = s; i != t; i = edge[curedge[i]].v)
{
tmp = curedge[i];
edge[tmp].cap -= cur_flow;
edge[tmp].flow += cur_flow;
tmp = edge[tmp].pair;
edge[tmp].cap += cur_flow;
edge[tmp].flow -= cur_flow;
}
max_flow += cur_flow;
u = s;
}
/* if .... else ... */
for(i = curedge[u]; i != -1; i = edge[i].next)
if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)
break;
if(i != -1)
{
curedge[u] = i;
pre[edge[i].v] = u;
u = edge[i].v;
}else{
if(0 == --numb[dist[u]]) break;
curedge[u] = net[u];
for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)
if(edge[i].cap > 0)
tmp = tmp<dist[edge[i].v]?tmp:dist[edge[i].v];
dist[u] = tmp + 1;
++numb[dist[u]];
if(u != s) u = pre[u];
}
}
return max_flow;
}
int main()
{
int n,m,i,j,val,a,b;
index = 0;
scanf("%d%d",&n,&m);
s = n + 1;
t = n + 2;
nv = t;
memset(net,-1,sizeof(net));
for(i = 1;i <= n; ++i)
{
scanf("%d%d",&a,&b);
add(s,i,a);
add(i,t,b);
}
for(i = 1;i <= m; ++i)
{
scanf("%d%d%d",&a,&b,&val);
edge[index].next = net[a];
net[a] = index;
edge[index].v = b;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index+1;
++index;
edge[index].next = net[b];
net[b] = index;
edge[index].v = a;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index - 1;
++index;
}
printf("%d\n",ISAP());
return 0;
}
#include <cstdio>
#include <memory.h>
using namespace std;
#define MAXN 30020
#define MAXE 2000000
#define INF 0x3fffffff
int ne,nv,index,s,t,net[MAXN];
struct Edge{
int next,pair;
int v,cap,flow;
}edge[MAXE];
void add(const int& u,const int& v,const int& val)
{
edge[index].next = net[u];
net[u] = index;
edge[index].v = v;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index+1;
++index;
edge[index].next = net[v];
net[v] = index;
edge[index].v = u;
edge[index].cap = 0;
edge[index].flow = 0;
edge[index].pair = index - 1;
++index;
}
int ISAP()
{
long numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
long cur_flow,max_flow,u,tmp,neck,i;
memset(dist,0,sizeof(dist));
memset(numb,0,sizeof(numb));
for(i = 1 ; i <= nv ; ++i)
curedge[i] = net[i];
numb[nv] = nv;
max_flow = 0;
u = s;
while(dist[s] < nv)
{
/* first , check if has augmemt flow */
if(u == t)
{
cur_flow = INF;
for(i = s; i != t;i = edge[curedge[i]].v)
{
if(cur_flow > edge[curedge[i]].cap)
{
neck = i;
cur_flow = edge[curedge[i]].cap;
}
}
for(i = s; i != t; i = edge[curedge[i]].v)
{
tmp = curedge[i];
edge[tmp].cap -= cur_flow;
edge[tmp].flow += cur_flow;
tmp = edge[tmp].pair;
edge[tmp].cap += cur_flow;
edge[tmp].flow -= cur_flow;
}
max_flow += cur_flow;
u = s;
}
/* if .... else ... */
for(i = curedge[u]; i != -1; i = edge[i].next)
if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)
break;
if(i != -1)
{
curedge[u] = i;
pre[edge[i].v] = u;
u = edge[i].v;
}else{
if(0 == --numb[dist[u]]) break;
curedge[u] = net[u];
for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)
if(edge[i].cap > 0)
tmp = tmp<dist[edge[i].v]?tmp:dist[edge[i].v];
dist[u] = tmp + 1;
++numb[dist[u]];
if(u != s) u = pre[u];
}
}
return max_flow;
}
int main()
{
int n,m,i,j,val,a,b;
index = 0;
scanf("%d%d",&n,&m);
s = n + 1;
t = n + 2;
nv = t;
memset(net,-1,sizeof(net));
for(i = 1;i <= n; ++i)
{
scanf("%d%d",&a,&b);
add(s,i,a);
add(i,t,b);
}
for(i = 1;i <= m; ++i)
{
scanf("%d%d%d",&a,&b,&val);
edge[index].next = net[a];
net[a] = index;
edge[index].v = b;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index+1;
++index;
edge[index].next = net[b];
net[b] = index;
edge[index].v = a;
edge[index].cap = val;
edge[index].flow = 0;
edge[index].pair = index - 1;
++index;
}
printf("%d\n",ISAP());
return 0;
}