原题地址:点击打开链接
思路:该题让求最少需要封的道路条数,即最小割。建立超级源点0,并与敌人所在的城市建边,容量设为最大值MAX,其他点之间的容量都设为1,则该题即转化为求最大流问题。
#include<stdio.h>
#include<string.h>
#define MAX 29999
int map[210][210],used[210],pre[210],n,m;
bool dfs(int u)
{
int v;
if(u==n)
return true;
for(v=1;v<=n;v++)
{
if(map[u][v]>0&&used[v]!=1)
{
used[v]=1;
pre[v]=u;
if(dfs(v))
return true;
}
}
return false;
}
int max_flow()
{
int u,v,res=0;
while(1)
{
memset(used,0,sizeof(used));
if(!dfs(0)) //寻找增广路
break;
res++;
v=n;
for(u=pre[n];v!=0;u=pre[u]) //更新该增广路上的流量
{
map[u][v]-=1;
map[v][u]+=1;
v=u;
}
}
return res;
}
int main()
{
int u,v,t,p,i,k=1;
scanf("%d",&t);
while(k<=t)
{
memset(map,0,sizeof(map));
scanf("%d%d%d",&n,&m,&p);
for(i=0;i<p;i++) //创建超级源点0,并连通至敌人所在的城市
{
scanf("%d",&v);
map[0][v]=MAX;
}
for(i=0;i<m;i++)
{
scanf("%d%d",&u,&v); //流量都初始化为1
map[u][v]=1;
map[v][u]=1;
}
int res=max_flow();
printf("Case #%d: %d\n",k++,res);
}
return 0;
}