1067 - Tunnels

在一个复杂的火山基地中,一名狡猾的间谍已经越狱并偷走了你的世界统治计划。作为基地的监控者,你通过观察他的行动轨迹,运用图论策略来计算最少需要破坏多少隧道才能阻止他逃出基地。

Curses! A handsome spy has somehow escaped from your elaborate deathtrap, overpowered your guards, and stolen your secret world domination plans. Now he is running loose in your volcano base, risking your entire evil operation. He must be stopped before he escapes!

Fortunately, you are watching the spy's progress from your secret control room, and you have planned for just such an eventuality. Your base consists of a complicated network of rooms connected by non-intersecting tunnels. Every room has a closed-circuit camera in it (allowing you to track the spy wherever he goes), and every tunnel has a small explosive charge in it, powerful enough to permanently collapse it. The spy is too quick to be caught in a collapse, so you'll have to strategically collapse tunnels to prevent him from traveling from his initial room to the outside of your base.

Damage to your base will be expensive to repair, so you'd like to ruin as few tunnels as possible. Find a strategy that minimizes the number of tunnels you'll need to collapse, no matter how clever the spy is. To be safe, you'll have to assume that the spy knows all about your tunnel system. Your main advantage is the fact that you can collapse tunnels whenever you like, based on your observations as the spy moves through the tunnels.

Input 

The input consists of several test cases. Each test case begins with a line containing integers R (1$ \le$R$ \le$50) and T (1$ \le$T$ \le$1000) , which are the number of rooms and tunnels in your base respectively. Rooms are numbered from 1 to R . T lines follow, each with two integers x , y (0$ \le$xy$ \le$R) , which are the room numbers on either end of a tunnel; a 0 indicates that the tunnel connects to the outside. More than one tunnel may connect a pair of rooms.

The spy always starts out in room 1. Input is terminated by a line containing two zeros.

Output 

For each test case, print a line containing the test case number (beginning with 1) followed by the minimum number of tunnels that must be collapsed, in the worst case. Use the sample output format and print a blank line after each test case.

Sample Input 

4 6 
1 2 
1 3 
2 4 
3 4 
4 0 
4 0 
4 6 
1 2 
1 3 
1 4 
2 0 
3 0 
4 0 
0 0

Sample Output 

Case 1: 2 

Case 2: 2





#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=105;
int cap[maxn][maxn],flow[maxn][maxn];
int n,m;
int x,y;
bool vis[maxn];
int M[maxn];
bool useful[maxn];

bool init()
{
	int i,x,y;
	scanf("%d %d",&n,&m);
	if(n==0&&m==0)
		return false;
	memset(cap,0,sizeof(cap));
	for(i=0;i<m;i++)
	{
		scanf("%d %d",&x,&y);
		cap[x][y]++;
		cap[y][x]++;
	}
	return true;
}

bool dfs(int x)
{
	if(x==0)
		return true;
	if(vis[x])
		return false;
	vis[x]=true;
	for(int i=0;i<=n;i++)
		if(cap[x][i]>flow[x][i]&&dfs(i))
		{
			flow[x][i]++;
			flow[i][x]--;
			return true;
		}
	return false;
}

int maxflow(int sink)
{
	int res=0;
	memset(flow,0,sizeof(flow));
	memset(vis,0,sizeof(vis));
	while(dfs(sink))
	{
		memset(vis,0,sizeof(vis));
		res++;
	}
	return res;
}

void del(int x)
{
	for(int i=0;i<=n;i++)
		cap[i][x]=cap[x][i]=0;
}

int main()
{
	int test=0;
	while(init())
	{
		for(int i=1;i<=n;i++)
			M[i]=maxflow(i);
		memset(useful,0,sizeof(useful));
		for(int i=1;i<=n;i++)
		{
			int m=2147483647;
			for(int j=1;j<=n;j++)
				if(useful[j]==0 && M[j]<m)
					m=M[j];
			for(int j=1;j<=n;j++)
				if(m==M[j])
				{
					useful[j]=true;
					del(j);
				}
				for(int j=1;j<=n;j++)
					if(useful[j]==0)
					{
						M[j]=min(M[j],m+maxflow(j));
					}
		}
		printf("Case %d: %d\n\n",++test,M[1]);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不仅仅是寻找

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值