http://acm.hdu.edu.cn/showproblem.php?pid=2807
大致题意:给出n个m*m的矩阵,若存在三个互异的矩阵满足a*b = c,那么a,c之间存在权值为1的单向边。有询问u,v,输出uv之间的最短距离。
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#define LL long long
#define _LL __int64
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 85;
int n,m;
int a[maxn][maxn][maxn];
int Map[maxn][maxn];
void init()
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == j) Map[i][j] = 0;
else Map[i][j] = INF;
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
for(int k = 1; k <= m; k++)
scanf("%d",&a[i][j][k]);
}
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i == j) continue;
//任意两个矩阵相乘
int tmp[maxn][maxn];
memset(tmp,0,sizeof(tmp));
for(int x = 1; x <= m; x++)
{
for(int y = 1; y <= m; y++)
{
for(int z = 1; z <= m; z++)
tmp[x][y] += a[i][x][z] * a[j][z][y];
}
}
//枚举与tmp相等的矩阵
for(int k = 1; k <= n; k++)
{
if(k == i || k == j) continue;
int flag = 1;
for(int x = 1; x <= m; x++)
{
for(int y = 1; y <= m; y++)
{
if(a[k][x][y] != tmp[x][y])
{
flag = 0;
break;
}
}
if(!flag) break;
}
if(flag)
Map[i][k] = 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(Map[i][j] > Map[i][k] + Map[k][j])
Map[i][j] = Map[i][k] + Map[k][j];
}
}
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
if(n == 0 && m == 0) break;
init();
floyd();
int k;
scanf("%d",&k);
while(k--)
{
int u,v;
scanf("%d %d",&u,&v);
if(Map[u][v] == INF)
printf("Sorry\n");
else printf("%d\n",Map[u][v]);
}
}
return 0;
}