题目:http://acm.hdu.edu.cn/showproblem.php?pid=3491
注:拆点
源代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define inf 1e9
using namespace std;
typedef int typec;
const int N = 220, M = 40000;
int n,m,s,t,u,v,cas,ans;
int a[N];
struct FlowNetwork {
int e, head[N], d[N], vd[N], pre[N], cur[N];
int nxt[M], eu[M], ev[M];
typec c[M];
void init() { e = 0; memset(head,-1,sizeof(head)); }
void addedge(int u, int v, typec w) {
eu[e]=u; ev[e]=v; c[e]=w; nxt[e]=head[u]; head[u]=e++;
eu[e]=v; ev[e]=u; c[e]=0; nxt[e]=head[v]; head[v]=e++;
//无向图中第二个c[e]=w;
}
typec sap(int s, int t, int n){
int i, u;
memset(d,0,sizeof(d)); memset(vd,0,sizeof(vd));
vd[0] = n;
cur[u = s] = head[s];
pre[s] = -1;
typec temp, ans = 0;
while (d[s] < n) {
if(u == t){
for(temp = inf, i = pre[u]; ~i; i = pre[eu[i]])
temp = min(temp, c[i]);
for(i = pre[u]; ~i; i = pre[eu[i]]){
c[i] -= temp; c[i ^ 1] += temp;
}
ans += temp; u = s;
}
for (i = cur[u]; ~i; i = nxt[i])
//if (c[i] > eps && d[u] == d[ev[i]] + 1){
if (c[i] > 0 && d[u] == d[ev[i]] + 1){
cur[u] = i; //当前弧优化
pre[u = ev[i]] = i;
break;
}
if(i == -1){
cur[u] = head[u];
if (--vd[d[u]] == 0)break;
vd[++d[u]]++;
if(u != s)u = eu[pre[u]];
}
}
return ans;
}
};
int solve()
{
FlowNetwork tmp;
tmp.init();
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i!=s&&i!=t)
tmp.addedge(i,i+n,a[i]);
}
tmp.addedge(s,s+n,inf);
tmp.addedge(t,t+n,0);
for(int i=0;i<m;i++)
{
scanf("%d %d",&u,&v);
tmp.addedge(u+n,v,inf);
tmp.addedge(v+n,u,inf);
}
return tmp.sap(s,t,2*n);
}
int main()
{
//freopen("D:\\a.txt","r",stdin);
scanf("%d",&cas);
while(cas--)
{
scanf("%d %d %d %d",&n,&m,&s,&t);
ans=solve();
printf("%d\n",ans);
}
}