Problem Description
There are N cities in the country. Each city is represent by a matrix size of M*M. If city A, B and C satisfy that A*B = C, we say that there is a road from A to C with distance 1 (but that does not means there is a road from C to A). Now the king of the country wants to ask me some problems, in the format: Is there is a road from city X to Y? I have to answer the questions quickly, can you help me?
Input
Each test case contains a single integer N, M, indicating the number of cities in the country and the size of each city. The next following N blocks each block stands for a matrix size of M*M. Then a integer K means the number of questions the king will ask, the following K lines each contains two integers X, Y(1-based).The input is terminated by a set starting with N = M = 0. All integers are in the range [0, 80].
Output
For each test case, you should output one line for each question the king asked, if there is a road from city X to Y? Output the shortest distance from X to Y. If not, output "Sorry".
Sample Input
3 2
1 1
2 2
1 1
1 1
2 2
4 4
1
1 3
3 2
1 1
2 2
1 1
1 1
2 2
4 3
1
1 3
0 0
Sample Output
1
Sorry
Source
此题要先找出哪些城市可以连边,可以通过矩阵相乘来实现,得出的矩阵与第三个矩阵比较,看看是否可以连边。
算出所有edge后,再通过floyd来算出任意两个城市的最短距离。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #include<set> 6 using namespace std; 7 #define inf 1<<26 8 #define N 86 9 int n,m; 10 int edge[N][N]; 11 struct Matrix 12 { 13 int mp[N][N]; 14 }matrix[N]; 15 Matrix Mul(Matrix a,Matrix b) 16 { 17 Matrix res; 18 for(int i=1;i<=m;i++) 19 { 20 for(int j=1;j<=m;j++) 21 { 22 res.mp[i][j]=0; 23 for(int k=1;k<=m;k++) 24 { 25 res.mp[i][j]=res.mp[i][j]+(a.mp[i][k]*b.mp[k][j]); 26 } 27 } 28 } 29 return res; 30 } 31 bool judge(Matrix a,Matrix b) 32 { 33 for(int i=1;i<=m;i++) 34 { 35 for(int j=1;j<=m;j++) 36 { 37 if(a.mp[i][j]!=b.mp[i][j]) 38 return false; 39 } 40 } 41 return true; 42 } 43 void init() 44 { 45 for(int i=1;i<=n;i++) 46 { 47 for(int j=1;j<=n;j++) 48 { 49 if(i==j) 50 edge[i][j]=0; 51 else 52 { 53 edge[i][j]=inf; 54 } 55 } 56 } 57 } 58 void floyd() 59 { 60 for(int k=1;k<=n;k++) 61 { 62 for(int i=1;i<=n;i++) 63 { 64 for(int j=1;j<=n;j++) 65 { 66 if(edge[i][j]>edge[i][k]+edge[k][j]) 67 edge[i][j]=edge[i][k]+edge[k][j]; 68 } 69 } 70 } 71 } 72 int main() 73 { 74 while(scanf("%d%d",&n,&m)==2 && n+m) 75 { 76 //memset(edge,0,sizeof(edge)); 77 78 init(); 79 80 for(int i=1;i<=n;i++) 81 { 82 for(int j=1;j<=m;j++) 83 { 84 for(int k=1;k<=m;k++) 85 { 86 scanf("%d",&matrix[i].mp[j][k]); 87 } 88 } 89 } 90 for(int i=1;i<=n;i++) 91 { 92 for(int j=1;j<=n;j++) 93 { 94 if(i==j) 95 continue; 96 Matrix tmp = Mul(matrix[i],matrix[j]); 97 for(int k=1;k<=n;k++) 98 { 99 if(i==k || j==k) 100 continue; 101 if(judge(tmp,matrix[k])) 102 edge[i][k]=1; 103 } 104 } 105 } 106 107 floyd(); 108 109 int c; 110 scanf("%d",&c); 111 while(c--) 112 { 113 int u,v; 114 scanf("%d%d",&u,&v); 115 if(edge[u][v]!=inf) 116 printf("%d ",edge[u][v]); 117 else 118 printf("Sorry "); 119 } 120 } 121 return 0; 122 }