变色龙(Floyd算法)
变色龙
避役(学名:Chamaeleonidae)(英语:chameleon)俗称变色龙,蜥蜴亚目(Sauria)避役科(Chamaeleontidae)爬行类,产于东半球。特征为体色能变化,它在每天会进行变色,可以变成N种颜色之一,将这些颜色标号为0,1,2...N-1。最近研究发现变色龙不是靠色素细胞变色,而是靠体内的基因,变色龙的基因内存在一个变色矩阵,记为Genemap,如果Genemap[i][j] = 'Y',则变色龙可以在某天从颜色i变成颜色j(一天不可以变色多次),如果Genemap[i][j] =‘N’则不能从i变成j色。最新又发现,变色龙的变色不是任意变的,它有一定的规律,这个规律是在某天,如果只有一种可以改变的颜色,它就变为这种颜色,如果有多种可以改变的颜色,那么它变为标号最小的颜色,如果不存在任何一种可以改变的颜色,那就不变色,注意可以变色时它一定会变色。小明在淘宝上买了一只颜色为0的变色龙,他想让这只变色龙变为颜色N-1,然后他向当地医院求助,医生有一项技术可以改变变色龙的一些基因,但需要花费高昂的代价,具体说小明可以花费1万元的代价,让医生将变色龙的变色矩阵中的某一个Genemap[i][j] = 'Y'改变成Genemap[i][j] = 'N'。问至少花费多少总代价改变变色龙的基因,让变色龙按它的变色规律可以从颜色0经过若干天的变色变成颜色N-1。如果一定不能变成N-1,则输出-1.
Input
第一行一个整数T(1<=T<=5),表示测试数据数量,每组测试数据有相同的结构构成: 每组数据第一行一个整数N(2<=N<=50)。 之后有N行,每行N个字符,表示变色龙的变色矩阵,矩阵中只有‘Y’与‘N’两种字符,第i行第j列的字符就是Genemap[i][j]。
Output
每组数据一行输出,即最小代价,无解时输出-1
Sample Input 1
3
3
NYN
YNY
NNN
8
NNNNNNNY
NNNNYYYY
YNNNNYYN
NNNNNYYY
YYYNNNNN
YNYNYNYN
NYNYNYNY
YYYYYYYN
6
NYYYYN
YNYYYN
YYNYYN
YYYNYN
YYYYNN
YYYYYN
Sample Output 1
1 0 -1
题解:要想从颜色i变成颜色j,需要Genemap[i][0]到Genemap[i][j-1]没有出现Y,如果出现,需改成N,即两点之间的花费加一。转化为求Genemap[i][0]到Genemap[i][j]的最短路问题。
特别注意Floyd算法中三重循环i,j,k的顺序。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #define inf 0x3f3f3f3f
6 using namespace std;
7 const int maxn=100;
8 char s[maxn][maxn];
9 int map[maxn][maxn];
10 int main()
11 {
12 int n,casen;
13 cin>>casen;
14 while(casen--)
15 {
16 memset(map,inf,sizeof(map));
17 scanf("%d",&n);
18 for(int i=0;i<n;i++)
19 {
20 int cnt=0;
21 scanf("%s",s[i]);
22 for(int j=0;j<n;j++)
23 {
24 if(s[i][j]=='Y')
25 map[i][j]=cnt++;
26 }
27 }
28 for(int k=0;k<n;k++)//从i到j的最短距离需要经过0-n-1顶点进行中转
29 {
30 for(int i=0;i<n;i++)
31 {
32 for(int j=0;j<n;j++)
33 {
34 if(map[i][j]>map[i][k]+map[k][j])
35 map[i][j]=map[i][k]+map[k][j];
36 }
37 }
38 }
39 if(map[0][n-1]==inf)
40 printf("-1\n");
41 else
42 printf("%d\n",map[0][n-1]);
43 }
44 return 0;
45 }