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
1 Sorry
题意:城市一共有n个地点,每个地点是一个m*m的矩阵,当a*b=c时,说明a可以到达c,是单向边
思路:这道题一开始还真担心超时,虽然说只有50个点,但是在计算矩阵乘积的时候复杂度可不低,并且我也确实超时几次了,我很疑惑一开始将getmp函数写在主函数里面超时,但是作为调用函数就不超时了,这是为什么呢?
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define inf 99999999 int n,m; int map[85][85]; int a[85][85][85],tem[85][85]; void Floyd() { int i,j,k; for(i = 1; i<=n; i++) for(j = 1; j<=n; j++) for(k = 1; k<=n; k++) if(map[j][i]+map[i][k]<map[j][k]) map[j][k] = map[j][i]+map[i][k]; } void getmap() { int i,j,k,x,y,z; for(i = 1; i<=n; i++) for(j = 1; j<=m; j++) for(k = 1; k<=m; k++) scanf("%d",&a[i][j][k]); for(i = 0; i<=n; i++) { for(j = 0; j<=n; j++) { if(i == j) map[i][j] = 0; else map[i][j] = inf; } } for(i = 1; i<=n; i++) { for(j = 1; j<=n; j++) { if(i==j) continue; memset(tem,0,sizeof(tem)); for(x = 1; x<=m; x++)//矩阵相乘 { for(y = 1; y<=m; y++) { tem[x][y] = 0; for(z = 1; z<=m; z++) { tem[x][y]+=a[i][x][z]*a[j][z][y]; } } } for(x = 1; x<=n; x++) { if(x == i || x == j) continue; int flag = 1; for(y = 1; y<=m; y++) { for(z=1; z<=m; z++) { if(tem[y][z]!=a[x][y][z]) { flag = 0; break; } } if(!flag) break; } if(flag) map[i][x] = 1; } } } Floyd(); } int main() { int i,k,j,x,y,z; while(scanf("%d%d",&n,&m)) { if(n==0 && m == 0) break; getmap(); scanf("%d",&z); while(z--) { scanf("%d%d",&x,&y); if(map[x][y] == inf) printf("Sorry\n"); else printf("%d\n",map[x][y]); } } return 0; }