chapter05—Alien Security(POJ 1130)

Description

Youare 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 theguests can be trusted, so they are assigned different security clearancelevels. Only guests with a level 5 rating will be allowed into the lab wherethe extra-terrestrial is being held; other than that, everyone is free to roamthroughout the rest of the facility. Each room in the facility is connected viaone-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 theET, but not in the room itself ?the guards do not have sufficient clearance toenter the room containing the ET.

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

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

2. There is no other room with this property that is closer to the roomcontaining the ET ?remember, the guards cannot be placed in the room containingthe ET itself.

The diagram below illustrates one possible map of your facility: 


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

Input

All guestsenter through room 0, the entrance to your facility. Your program accepts asequence 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 ownfree will, of course). 

The rest of the input is a sequence of linesconsisting of only two integers, specifying where the airlock-doors arelocated. The first number on these lines specifies the source room, and thesecond the destination room. Remember: you can pass only from the source roomto the destination room.

Output

Theoutput 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.

SampleInput

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

SampleOutput

Put guards in room 3.

Source

Southern African2001

 

 

题目的大概意思:

      一家高度机密的政府研究机构有多个房间,其中一个房间有外星人(ET),不是所有的参观人员都能够进入含有外星人的房间;所以需要在某个房间设置门卫,设置门卫的房间必须满足两个条件;

1),要参观到外星人,必须通过守卫的房间;

2),没有其他的房间比守卫的房间更接近外星人;

(出发地点在房间0)

输入的样例:

第一行为样例的总数;

开始:房间的总数  外星人所在的房间的位置

房间源 -> 目的房间等等 EOF结束


分析:从两个条件出发;

不妨可以用单源最短路径,分别求出每个房间离ET的举例;然后从最短的路劲开始枚举,假如去除掉该房间,能否使参观者从0到ET房间,如果不能达到,那么该房间就是我们要设置门卫的房间;

代码如下:

package ACM;

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;


public class Main {
	private int[][] g;
	private int[] dis;
	private boolean[] used;
	
	public Main(int n) {
		g = new int[n][n];
		dis = new int[n];
		used = new boolean[n];
		resetAllVertex();
	}

	public void addEdge(int start, int end) {
		g[start][end] = 1;
	}

	private void resetAllVertex() {
		// TODO Auto-generated method stub
		for (int i = 0; i < g.length; i++) {
			Arrays.fill(g[i], 0);
		}
		Arrays.fill(dis, -1);
		Arrays.fill(used, false);
	}

	public int getGuardRoom(int eT) {
		// TODO Auto-generated method stub
		// 广度遍历,获得的从近到远的排序;
		Iterator it = BFSTraverse(eT);
		int temp;
		while (it.hasNext()) {
			temp = (Integer)it.next();
			Arrays.fill(used, false);
			// temp表示取消掉该房间;看是否能够到达房间ET,我们的目的是找到一个temp使参观者不能到房间ET
			if (!canGoToET(temp, eT)) {
				return temp;
			}
		}
		
		return 0;
	}

	private boolean canGoToET(int temp, int eT) {
		// TODO Auto-generated method stub
		used[temp] = true;
		// 继续广度遍历,从0点开始;
		// 这个是用来辅助完成广度遍历的
		LinkedList<Integer> llisttemp = new LinkedList<Integer>();
		llisttemp.add(0);
		used[0] = true;
		int vert;

		while (llisttemp.size() > 0) {
			vert = llisttemp.remove();
			for (int i = 0; i < g.length; i++) {
				
				if (g[vert][i] == 1 && !used[i]) {
					llisttemp.add(i);
					used[i] = true;
					if (i == eT) {
						return true;
					}
				}
			}
		}
		return false;
	}

	private Iterator BFSTraverse(int eT) {
		// TODO Auto-generated method stub
		// 这个是存放结果的,但是我们不需要存放eT
		LinkedList<Integer> llistans = new LinkedList<Integer>();
		// 这个是用来辅助完成广度遍历的
		LinkedList<Integer> llisttemp = new LinkedList<Integer>();

		dis[eT] = 0;
		llisttemp.add(eT);
		int vert;

		while (llisttemp.size() > 0) {
			vert = llisttemp.remove();
			for (int i = 0; i < g.length; i++) {
				// 注意取反向;
				if (g[i][vert] == 1 && dis[i] == -1) {
					dis[i] = dis[vert] + 1;
					llisttemp.add(i);
					llistans.add(i);
				}
			}
		}
		return llistans.iterator();
	}

	public static void main(String[] args) {
		// int n;
		int FJSum;
		int ET;
		int guardRoom;
		Main ma;
		String str;
		Scanner cin = new Scanner(new BufferedInputStream(System.in));
		// str = br.readLine();
		// n = Integer.parseInt(str);
		//
		// for(int i=0;i<n;i++){
		// str = br.readLine().trim();
		str = cin.nextLine().trim();
		StringTokenizer st = new StringTokenizer(str);

		FJSum = Integer.parseInt(st.nextToken());
		ET = Integer.parseInt(st.nextToken());

		ma = new Main(FJSum);
	
		while(cin.hasNext()){
			str = cin.nextLine();
			st = new StringTokenizer(str);
			ma.addEdge(Integer.parseInt(st.nextToken()),
					Integer.parseInt(st.nextToken()));
		}


		guardRoom = ma.getGuardRoom(ET);
		System.out.println("Put guards in room " + guardRoom + ".");

	}
}
注意,这道题的输入结束标志是EOF,在Eclipse中,可以在Windows->Preferences->General->Keys查看EOF的快捷键,默认情况下为Ctrl+Z









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值