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来算出任意两个城市的最短距离。
 
hdu 2807 The Shortest Path(矩阵+floyd)_sedhdu 2807 The Shortest Path(矩阵+floyd)_i++_02
  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\n",edge[u][v]);
117             else 
118               printf("Sorry\n");
119         }
120     }
121     return 0;
122 }
View Code