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









發佈了70 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章