题意还是比较好理解的,即如果矩阵A、B、C满足A*B=C,则代表矩阵A的第i个城市与代表矩阵B的第j个城市之间存在通路。。。
orz。。。然后我就按一般的矩阵相等的条件去判断。。。结果TLE了。。。2000MS+了。。。
然后就学了一下矩阵的优化。。。优化后。。。60MS。。orz。。。
一开始的代码:
1 #include<iostream> 2 const int N=100; 3 const int inf=10000000; 4 using namespace std; 5 6 int edge[N][N]; 7 int n,m; 8 struct Matrix{ 9 int map[N][N]; 10 }; 11 Matrix matrix[N],M; 12 13 Matrix calculate(const int &p,const int &q){ 14 Matrix Mat; 15 for(int i=1;i<=m;i++){ 16 for(int j=1;j<=m;j++){ 17 int ans=0; 18 for(int k=1;k<=m;k++){ 19 ans+=matrix[p].map[i][k]*matrix[q].map[k][j]; 20 } 21 Mat.map[i][j]=ans; 22 } 23 } 24 return Mat; 25 } 26 27 int cmp(const Matrix &p,const Matrix &q){ 28 for(int i=1;i<=m;i++){ 29 for(int j=1;j<=m;j++){ 30 if(p.map[i][j]!=q.map[i][j]) 31 return 0; 32 } 33 } 34 return 1; 35 } 36 37 void floyd(){ 38 for(int k=1;k<=n;k++){ 39 for(int i=1;i<=n;i++){ 40 //if(i==k||edge[i][k]==inf)continue; 41 for(int j=1;j<=n;j++){ 42 //if(i==k||j==k||edge[j][k]==inf)continue; 43 if(edge[i][j]>edge[i][k]+edge[k][j]){ 44 edge[i][j]=edge[i][k]+edge[k][j]; 45 } 46 } 47 } 48 } 49 } 50 51 52 int main(){ 53 while(scanf("%d%d",&n,&m)!=EOF&&n&&m){ 54 for(int i=1;i<=n;i++){ 55 edge[i][i]=0; 56 for(int j=i+1;j<=n;j++){ 57 edge[i][j]=edge[j][i]=inf; 58 } 59 } 60 for(int i=1;i<=n;i++){ 61 for(int j=1;j<=m;j++){ 62 for(int k=1;k<=m;k++){ 63 scanf("%d",&matrix[i].map[j][k]); 64 } 65 } 66 } 67 for(int i=1;i<=n;i++){ 68 for(int j=1;j<=n;j++){ 69 if(i==j)continue; 70 M=calculate(i,j); 71 for(int k=1;k<=n;k++){ 72 if(i==k||j==k)continue; 73 if(cmp(M,matrix[k])){ 74 edge[i][k]=1; 75 } 76 } 77 } 78 } 79 floyd(); 80 int t; 81 scanf("%d",&t); 82 while(t--){ 83 int v0,v; 84 scanf("%d%d",&v0,&v); 85 if(edge[v0][v]<inf){ 86 printf("%d\n",edge[v0][v]); 87 }else 88 printf("Sorry\n"); 89 } 90 } 91 return 0; 92 }
优化后的代码。。
1 #include<iostream> 2 const int N=100; 3 const int inf=10000000; 4 using namespace std; 5 6 int edge[N][N]; 7 int n,m; 8 struct Matrix{ 9 int map[N][N]; 10 }; 11 struct ReMatrix{ 12 int Map[N]; 13 }; 14 15 Matrix matrix[N]; 16 ReMatrix rematrix[N]; 17 18 void cmp(const int &a,const int &b){ 19 //判断矩阵是否相等 20 for(int i=1;i<=m;i++){ 21 if(rematrix[0].Map[i]!=rematrix[b].Map[i]) 22 return ; 23 } 24 edge[a][b]=1; 25 } 26 27 void CreateMap(const int &p,const int &q){ 28 for(int i=1;i<=m;i++){ 29 rematrix[0].Map[i]=0; 30 for(int j=1;j<=m;j++){ 31 rematrix[0].Map[i]+=matrix[p].map[i][j]*rematrix[q].Map[j]; //就是两个矩阵相乘。。 32 } 33 } 34 for(int i=1;i<=n;i++){ 35 if(i!=p&&i!=q)cmp(p,i); 36 } 37 } 38 39 40 void floyd(){ 41 for(int k=1;k<=n;k++){ 42 for(int i=1;i<=n;i++){ 43 //if(i==k||edge[i][k]==inf)continue; //加了就WA了 44 for(int j=1;j<=n;j++){ 45 //if(j==k||edge[j][k]==inf)continue; 46 if(edge[i][j]>edge[i][k]+edge[k][j]){ 47 edge[i][j]=edge[i][k]+edge[k][j]; 48 } 49 } 50 } 51 } 52 } 53 54 int main(){ 55 while(scanf("%d%d",&n,&m)!=EOF&&n&&m){ 56 for(int i=1;i<=n;i++){ 57 edge[i][i]=0; 58 for(int j=i+1;j<=n;j++){ 59 edge[i][j]=edge[j][i]=inf; 60 } 61 } 62 for(int i=1;i<=n;i++){ 63 for(int j=1;j<=m;j++){ 64 rematrix[i].Map[j]=0; 65 for(int k=1;k<=m;k++){ 66 scanf("%d",&matrix[i].map[j][k]); 67 rematrix[i].Map[j]+=matrix[i].map[j][k]*k; //化二维数组为一维数组,矩阵优化 68 } 69 } 70 } 71 for(int i=1;i<=n;i++){ 72 for(int j=1;j<=n;j++){ 73 if(i==j)continue; 74 else CreateMap(i,j); 75 } 76 } 77 floyd(); 78 int t; 79 scanf("%d",&t); 80 while(t--){ 81 int v0,v; 82 scanf("%d%d",&v0,&v); 83 if(edge[v0][v]<inf){ 84 printf("%d\n",edge[v0][v]); 85 }else 86 printf("Sorry\n"); 87 } 88 } 89 return 0; 90 }