Time Limit: 2000MS | Memory Limit: 32768KB | 64bit IO Format: %I64d & %I64u |
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?
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
HDU 2009-4 Programming Contest
题意:有 n 个矩阵,大小均为 m*m, 如果存在 A*B = C, 则A到C存在路径,且长度为1,询问 k 次,某两个矩阵是否存在最短路,有则输出最短路,没有输出 Sorry。数据均不超过 80
思路:用朴素矩阵乘法造图,再用 Floyd 求最短路。
<span style="font-size:18px;">#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const double PI = acos(-1.0);
const double e = 2.718281828459;
const double eps = 1e-8;
const int MAXN = 82;
const int INF = 1<<29;
struct Matrix {
int n, m;
int a[MAXN][MAXN];
void clear() {
n = m = 0;
memset(a, 0, sizeof(a));
}
} M[MAXN];
int n, m, k;
int w[MAXN][MAXN];
void Multi(Matrix a, Matrix b, Matrix &t) {
t.clear();
t.n = t.m = a.n;
for(int i = 1; i <= t.n; i++) {
for(int j = 1; j <= t.n; j++) {
for(int k = 1; k <= t.n; k++)
t.a[i][j] += a.a[i][k]*b.a[k][j];
}
}
}
int cmp(Matrix a, Matrix b) {
for(int i = 1; i <= a.n; i++) {
for(int j = 1; j <= a.n; j++) {
if(a.a[i][j] != b.a[i][j])
return 0;
}
}
return 1;
}
void Floyd() {
for(int k = 1; k <= n; k++) {
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
if(w[i][j] > w[i][k]+w[k][j])
w[i][j] = w[i][k]+w[k][j];
}
}
}
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int u, v;
while(cin>>n>>m) {
if(!n || !m)
break;
for(int i = 1; i <= n; i++)
M[i].clear();
for(int i = 1; i <= n; i++) {
M[i].n = M[i].m = m;
for(int j = 1; j <= m; j++)
for(int k = 1; k <= m; k++) {
scanf("%d", &M[i].a[j][k]);
}
}
scanf("%d", &k);
Matrix t;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
w[i][j] = (i==j)?0:INF;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
if(i == j)
continue;
Multi(M[i], M[j], t);
for(int k = 1; k <= n; k++) {
if(i==k || j==k)
continue;
if(cmp(t, M[k])) {
//printf("%d %d %d\n", i, j, k);
w[i][k] = 1;
}
}
}
}
Floyd();
while(k--) {
scanf("%d %d", &u, &v);
if(w[u][v] < INF)
printf("%d\n", w[u][v]);
else
printf("Sorry\n");
}
}
return 0;
}
</span>