您的位置:首页 > 其它

Sicily 1827 && 1947 Sniper

2010-07-20 15:30 375 查看
//求最小割,转化为最大流模型来求最大流
//构图的方法是拆点,将除了源点和汇点外的点1个变成2个,各自的容量为点的值。
//有相连的点之间的容量为正无穷,注意看清题意,题目说的是给你的2个点他们是相连的"connected",即双向连通,所以构图时要注意
//因为没注意到这点构图的时候错了WA了无数次,唉,我还是这么水~
#include<iostream>
#include<cstring>
#include<queue>
#define INF 1000000000
using namespace std;
int cap[105][105],flow[105][105],rflow[105],pre[105];
int t,n,m,st,ed,maxflow,x,y;
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(cap,0,sizeof(cap));
memset(flow,0,sizeof(flow));
for(int i = 1;i <= n - 1;++i)
scanf("%d",∩[i][i+n]);//拆点的步骤
maxflow = 0;
st = 0;
ed = n;
while(m--)
{
scanf("%d%d",&x,&y);
if(x != 0 && y != 0 && x != n && y != n)	cap[x+n][y] = cap[y+n][x] = INF;
if(x == 0)	cap[x][y] = INF;
if(y == 0)	cap[y][x] = INF;
if(x == n)	cap[y+n][x] = INF;
if(y == n)	cap[x+n][y] = INF;
//构图要注意题意,是无向图还是有向图
}
for(;;)//Edmonds-Karp
{
memset(rflow,0,sizeof(rflow));
queue<int> q;
q.push(st);
rflow[st] = INF;
while(!q.empty())
{
int u = q.front();
q.pop();
for(int v = 0;v <= 2*n;++v)
if(!rflow[v] && cap[u][v] > flow[u][v])
{
pre[v] = u;
q.push(v);
rflow[v] = min(rflow[u],cap[u][v] - flow[u][v]);
}
}
if(rflow[ed] == 0)	break;
for(int u = ed;u != st;u = pre[u])
{
flow[pre[u]][u] += rflow[ed];
flow[u][pre[u]] -= rflow[ed];
}
maxflow += rflow[ed];
}
printf("%d/n",maxflow);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: