http://acm.hdu.edu.cn/showproblem.php?pid=2807
题意 : 类似于最短路,不过几个city之间的联系是从他们的矩阵信息中所得到的。(矩阵A * 矩阵B = 矩阵C 则说明A 于 C 之间单向连通并且距离为1,PS : 但是并不是说明B可以连通C,因为矩阵乘法位置互换之后结果不一定相等)
思路 :矩阵乘法复杂度在O(M^3),而枚举每一组A,B,C复杂度又是O(N^3),一开始傻傻的去试了下,果断TLE。好吧,后来把 A * B的结果保存在新的矩阵里,再去寻找是否存在C,使得复杂度大约降到了O(M ^ 3 * N ^ 2),1900MS险过~~~~囧。
PS : 写矩阵的时候最好使用结构体,这样效率高。
//CNWSYCF
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int INF = 100000007;
const double eps = 1e-9;
const int maxn = 100;
#define MIN(a,b) (a > b ? b : a)
#define MAX(a,b) (a > b ? a : b)
struct node
{
int mat[maxn][maxn];
}q[maxn],temp;
struct gogo
{
int mat[maxn][maxn];
}New[maxn][maxn];
int N,M,G[maxn][maxn];
bool Pd(int a,int b,int c)
{
for (int i=1;i<=M;i++)
for (int j=1;j<=M;j++)
if (q[c].mat[i][j] != New[a][b].mat[i][j])return 0;
return 1;
}
void init()
{
for (int i=1;i<=N;i++)
for (int j=1;j<=N;j++)
if (i != j)G[i][j] = INF;
else G[i][j] = 0;
}
void Floyd()
{
for (int k=1;k<=N;k++)
for (int i=1;i<=N;i++)
for (int j=1;j<=N;j++)
G[i][j] = MIN(G[i][k] + G[k][j] , G[i][j]);
}
void Add(int a,int b)
{
for (int i=1;i<=M;i++)
for (int j=1;j<=M;j++)
{
int sum = 0;
for (int k=1;k<=M;k++)
sum += q[a].mat[i][k] * q[b].mat[k][j];
New[a][b].mat[i][j] = sum;
}
}
int main()
{
while (scanf("%d%d",&N,&M) && (N || M))
{
init();
for (int c=1;c<=N;c++)
{
for (int i=1;i<=M;i++)
for (int j=1;j<=M;j++)
scanf("%d",&q[c].mat[i][j]);
}
for (int i=1;i<=N;i++)
for (int j=1;j<=N;j++)
Add(i,j);
for (int k=1;k<=N;k++)
for (int i=1;i<=N;i++)
for (int j=1;j<=N;j++)
if ((i != j && j!= k && k != i) && Pd(i,j,k))
{
G[i][k] = 1;
//G[j][k] = 1;
}
Floyd();
int Q;
scanf("%d",&Q);
while (Q--)
{
int a,b;
scanf("%d%d",&a,&b);
if (G[a][b] < INF)printf("%d\n",G[a][b]);
else printf("Sorry\n");
}
}
return 0;
}