chapter05-Hike on a Graph(POJ 2415)

来源:互联网 发布:数控车床滚花编程 编辑:程序博客网 时间:2024/06/06 09:15

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 numbern. Input is terminated by n=0.Otherwise, 1<=n<=50. Then follow three integersp1,p2, p3 with 1<=pi<=n denotingthe starting locations of the game pieces. The colours of the arrows are givennext as am×m matrix of whitespace-separated lower-case letters. Theelement mij denotes the colour of the arrow between thelocationsi 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;//移动第一个棋子 p1for(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);}}//移动第一个棋子 p2for(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);}}//移动第一个棋子 p3for(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 stubint 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;}}}






0 0
原创粉丝点击