Risk is a board game in which several opposing playersattempt to conquer the world. The gameboard consists of a world map broken upinto hypothetical countries. During a player‘s turn, armies stationed in onecountry are only allowed to attack
only countries with which they share acommon border. Upon conquest of that country, the armies may move into thenewly conquered country.
During the course of play, a player often engages in a sequence of conquestswith the goal of transferring a large mass of armies from some starting countryto a destination country. Typically, one chooses the intervening countries soas to minimize the total
number of countries that need to be conquered. Given adescription of the gameboard with 20 countries each with between 1 and 19connections to other countries, your task is to write a function that takes astarting country and a destination country and computes
the minimum number ofcountries that must be conquered to reach the destination. You do not need tooutput the sequence of countries, just the number of countries to be conqueredincluding the destination. For example, if starting and destination countriesare
neighbors, then your program should return one.
The following connection diagram illustrates the first sample input.
Input
Input to your program will consist of a series of countryconfiguration test sets. Each test set will consist of a board description onlines 1 through 19. The representation avoids listing every national boundarytwice by only listing the fact
that country I borders country J when I < J.Thus, the Ith line, where I is less than 20, contains an integer X indicatinghow many "higher-numbered" countries share borders with country I,then X distinct integers J greater than I and not exceeding 20, each
describinga boundary between countries I and J. Line 20 of the test set contains a singleinteger (1 <= N <= 100) indicating the number of country pairs thatfollow. The next N lines each contain exactly two integers (1 <= A,B <=20; A!=B) indicating the starting
and ending countries for a possible conquest.
There can be multiple test sets in the input file; your program should continuereading and processing until reaching the end of file. There will be at leastone path between any two given countries in every country configuration.
Output
For each input set, your program should print thefollowing message "Test Set #T" where T is the number of the test setstarting with 1. The next NT lines each will contain the result for thecorresponding test in the test set - that is, the minimum
number of countriesto conquer. The test result line should contain the start country code A thestring " to " the destination country code B ; the string ":" and a single integer indicating the minimum number of moves required totraverse from country A to country
B in the test set. Following all result linesof each input set, your program should print a single blank line.
Sample Input
1 3
2 3 4
3 4 5 6
1 6
1 7
2 12 13
1 8
2 9 10
1 11
1 11
2 12 17
1 14
2 14 15
2 15 16
1 16
1 19
2 18 19
1 20
1 20
5
1 20
2 9
19 5
18 19
16 20
Sample Output
Test Set #1
1 to 20: 7
2 to 9: 5
19 to 5: 6
18 to 19: 2
16 to 20: 2
题目分析:题意给出国家间的邻接关系,求从一个国家到另一个国家所经过的最少国家数。构建图每条边权为1,然后用floyd算法即可。另也可以用bfs。
Floyd算法用于求最短路径。三个for循环就可以解决问题,所以它的时间复杂度为O(n^3)。
Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB)= Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int cost[25][25]; //图的权
int main()
{
int n,m,ca=1;
int a,t;
while(~scanf("%d",&a)){
memset(cost,11,sizeof(cost));
for(int i=1;i<=a;++i){
scanf("%d",&t);
cost[1][t]=cost[t][1]=1;
}
for(int i=2;i<=19;++i){
scanf("%d",&t);
for(int j=1;j<=t;++j){
int x;
scanf("%d",&x);
cost[i][x]=cost[x][i]=1;
}
}
for(int k=1;k<=20;++k) //floyd
for(int i=1;i<=20;++i)
for(int j=1;j<=20;++j)
cost[i][j]=min(cost[i][k]+cost[k][j],cost[i][j]);
scanf("%d",&m);
printf("Test Set #%d\n",ca++);
for(int i=0;i<m;++i){
int a,b;
scanf("%d%d",&a,&b);
printf("%d to %d: %d\n",a,b,cost[a][b]);
}
printf("\n");
}
return 0;
}