ZOJ 1085 Alien Security(SPFA+dfs)

Alien Security

Time Limit: 2 Seconds       Memory Limit: 65536 KB

You are in charge of security at a top-secret government research facility. Recently your government has captured a live extra-terrestrial (ET) life form, and is hosting an open day for fellow researchers. Of course, not all the guests can be trusted, so they are assigned different security clearance levels. Only guests with a level 5 rating will be allowed into the lab where the extra-terrestrial is being held; other than that, everyone is free to roam throughout the rest of the facility. Each room in the facility is connected via one-way airlocks, so that you can pass through the door in only one direction.

To protect your precious ET you will put in place enhanced security measures (in the form of armed guards) on the route leading to the room containing the ET, but not in the room itself �C the guards do not have sufficient clearance to enter the room containing the ET.

The guards will check the identity and the security rating of all guests trying to pass through the room in which they are stationed, so you would like to place the guards where they will cause the minimum amount of irritation to the guests who have no intention of visiting the ET. The room where the guards must be placed thus satisfies the following two conditions:

1. In order to get to the room containing the ET, the guests must pass through the room containing the guards;

2. There is no other room with this property that is closer to the room containing the ET �C remember, the guards cannot be placed in the room containing the ET itself.

The diagram below illustrates one possible map of your facility:

Note that placing the guards in room 2 would satisfy the first condition, but room 3 is closer to the ET, so the guards must be placed in room 3.

All guests enter through room 0, the entrance to your facility. Your program accepts a sequence of lines containing integers. The first line consists of two integers: the number of rooms, and the room in which the ET is being held (out of his own free will, of course).

The rest of the input is a sequence of lines consisting of only two integers, specifying where the airlock-doors are located. The first number on these lines specifies the source room, and the second the destination room. Remember: you can pass only from the source room to the destination room.

The output of your program consists only of a single line:

Put guards in room N.

where N is the room you've decided to place the guards.


This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.


SAMPLE INPUT

This input sequence specifies the map shown above.

1

9 4
0 2
2 3
3 4
5 3
5 4
3 6
6 5
6 7
6 8
4 7
0 1
1 7
7 0


SAMPLE OUTPUT

Put guards in room 3. 


Source:  South Africa 2001


通过题意可知要确定守卫房间,显然要知道以下两点:(1)确定客人要参观到ET,必经的房间;(2)从必经的房间中,选择距ET房间最近的房间(且不能设置在ET房间内)。实现:首先通过SPFA求ET到各个房间的最短距离,然后枚举各个房间,确定必经之路,既然是必经之路,那么删除此结点,显然无法到达ET房间,最后选择距离ET房间最短的房间记录保存即可。


AC代码:

#include <bits/stdc++.h>
using namespace std;

const int MaxN = 100;
int n, et;
bool used[MaxN];
bool data[MaxN][MaxN];
int dis[MaxN];

void SPFA() {
	queue<int> q; 
	q.push(et);
	dis[et] = 0;
	int x;
	while (!q.empty()){
		x = q.front();
		q.pop();
		for (int i = 0; i < n; ++i)
			if (data[i][x] && dis[x] + 1 < dis[i]){
				q.push(i);
				dis[i] = dis[x] + 1;
			}
	}
}

int dfs(int id){
	if (id == et) return 1;
	used[id] = 1;
	for (int i = 0; i <n; ++i)
		if (!used[i] && data[id][i])
			if (dfs(i)) return 1;
	return 0;
}

int main(){
	int cases;
	int room;
	scanf("%d", &cases);
	for (int t = 0; t < cases; ++t){
		scanf("%d%d\n", &n, &et);
		memset(data, 0, sizeof(data));
		for (int i = 0; i < MaxN; ++i) 
			dis[i] = INT_MAX;
		char line[10];
		int a, b;
		while (gets(line)){
			if (strcmp(line, "")==0) break;
			sscanf(line, "%d%d", &a, &b);
			data[a][b] = true;
		}
		
		SPFA();
		
		//房间0显然是必经之路 
		int d = dis[0];
		room = 0;
		for (int i = 1; i < n; ++i){//枚举必经之路 
			if (i == et) continue;
			memset(used, 0, sizeof(used));
			used[i] = 1;
			//从入口0不能到达ET,说明i是必经之路 
			if (!dfs(0) && dis[i] < d){
				room = i;
				d = dis[i];
			}
		}
		
		if (t) cout << endl;
		cout << "Put guards in room " << room << "." << endl;
	}
	return 0;
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值