chapter05-Hike on a Graph(POJ 2415)

Hike on a Graph


Time Limit: 2 Seconds      Memory Limit: 65536 KB


"Hike on a Graph" is a game that is playedon a board on which an undirected graph is drawn. The graph is complete and hasall loops, i.e. for any two locations there is exactly one arrow between them.The arrows are coloured. There are three players, and each of them has a piece.At the beginning of the game, the three pieces are in fixed locations on thegraph. In turn, the players may do a move. A move consists of moving one's ownpiece along an arrow to a new location on the board. The following constraintis imposed on this: the piece may only be moved along arrows of the same colouras the arrow between the two opponents' pieces.

In the sixties ("make love not war") aone-person variant of the game emerged. In this variant one person moves allthe three pieces, not necessarily one after the other, but of course only oneat a time. Goal of this game is to get all pieces onto the same location, usingas few moves as possible. Find out the smallest number of moves that isnecessary to get all three pieces onto the same location, for a given boardlayout and starting positions.

Input Specification

The input file contains several test cases. Each testcase starts with the number n. Input is terminated by n=0.Otherwise, 1<=n<=50. Then follow three integers p1,p2, p3 with 1<=pi<=n denotingthe starting locations of the game pieces. The colours of the arrows are givennext as a m×m matrix of whitespace-separated lower-case letters. Theelement mij denotes the colour of the arrow between thelocations i and j. Since the graph is undirected, you can assumethe matrix to be symmetrical.

Output Specification

For each test case output on a single line the minimumnumber of moves required to get all three pieces onto the same location, or theword "impossible" if that is not possible for the given board andstarting locations.

Sample Input

3 1 2 3

r b r

b b b

r b r

2 1 2 2

y g

g y

0

ample Output

2

Impossible



題目大意:

         這道題還真不是那麼好讀懂,看了半天。。暈。。。

講的就是一個完全無向圖(任意兩點都相連,也都有自連邊),頂點個數爲n(1<=n<=50);每條邊都有一種顏色(用小寫字母表示),現在有三顆棋子(固定有且只有三個),他們的初始位置分別爲p1,p2,p3,現在要求移動這些棋子,使其能夠移動三顆到達同一個點的最小步數?棋子能夠移動的條件的,當棋子要移動的位置的邊的顏色與另外兩顆棋子的邊的顏色一樣;(注意:自連邊的目的就是當兩顆棋子處於一個位置時,他們之間的邊就是自連邊哈)

 

分析:利用窮舉的

方法,遍歷他們可以到達的點的任意組合;

用廣度搜索的方法:有隊列Q

一次計算的內容包括p1,p2,p3,

將p1能夠到達的所有位置和p2,p3一起存入隊列;

將p2能夠到達的所有位置和p1,p3一起存入隊列;

將p3能夠到達的所有位置和p1,p2一起存入隊列;

(當然以上所有的步數都僅僅算一次,還要判斷相關條件);

因此需要三維數組dis[][][]來存儲這些組合的步數;

已知dis[p1][p2][p3]=0

 

代碼如下:

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

public class Main {
	
	private int[][][] dis;
	private char[][] color;
	
	private static int p1;
	private static int p2;
	private static int p3;
	
	public Main(int n){
		dis = new int[n][n][n];
		color = new char[n][n];
		
		for(int i=0;i<n;i++){
			for(int j=0;j<n;j++){
				Arrays.fill(dis[i][j], -1);
			}
		}
	}
	
	public int getCountSum(){
	
		LinkedList<node> llist = new LinkedList<node>();
		node vernode;
		vernode = new node(p1,p2,p3);
		
		if(vernode.isRightAns()){
			return 0;
		}
		
		llist.add(vernode);
		dis[p1][p2][p3] = 0;
		
		//因爲是廣度遍歷,所以得到的第一個相等的數必然是最小步數的數
		while(llist.size()>0){
			int x,y,z;
			vernode = llist.remove();
			
			x = vernode.x;
			y = vernode.y;
			z = vernode.z;
			//移動第一個棋子 p1
			for(int i=0;i<dis.length;i++){
				if(color[x][i] == color[y][z] && x!=i && dis[i][y][z] == -1){
					dis[i][y][z] = dis[x][y][z]+1;
					vernode = new node(i,y,z);
					if(vernode.isRightAns()){
						return dis[i][y][z];
					}
					llist.add(vernode);
				}
			}
			//移動第一個棋子 p2
			for(int i=0;i<dis.length;i++){
				if(color[y][i] == color[x][z] && y!=i && dis[x][i][z] == -1){
					dis[x][i][z] = dis[x][y][z]+1;
					vernode = new node(x,i,z);
					if(vernode.isRightAns()){
						return dis[x][i][z];
					}
					llist.add(vernode);
				}
			}
			
			//移動第一個棋子 p3
			for(int i=0;i<dis.length;i++){
				if(color[z][i] == color[x][y] && z!=i && dis[x][y][i] == -1){
					dis[x][y][i] = dis[x][y][z]+1;
					vernode = new node(x,y,i);
					if(vernode.isRightAns()){
						return dis[x][y][i];
					}
					llist.add(vernode);
				}
			}
		}
		
		return -1;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int n;
		Main ma;
		int temp;
		Scanner cin = new Scanner(new BufferedInputStream(System.in));

		while((n= cin.nextInt()) != 0){
			ma = new Main(n);
			p1 = cin.nextInt()-1;
			p2 = cin.nextInt()-1;
			p3 = cin.nextInt()-1;
			
			for(int i =0;i<n;i++){
				for(int j=0;j<n;j++){
					ma.color[i][j] = cin.next().charAt(0);
				}
			}
			
			if((temp =ma.getCountSum() )== -1){
				System.out.println("impossible");
			}else{
				System.out.println(temp);
			}
		}
	}
	class node{
		public int x, y, z;
		public node(int x,int y,int z){
			this.x = x;
			this.y = y;
			this.z = z;
		}
		public boolean isRightAns(){
			if(x == y && y ==z){
				return true;
			}
			return false;
		}
	}

}






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