hdu 2807 矩阵比较+floyd

题意还是比较好理解的,即如果矩阵A、B、C满足A*B=C,则代表矩阵A的第i个城市与代表矩阵B的第j个城市之间存在通路。。。

orz。。。然后我就按一般的矩阵相等的条件去判断。。。结果TLE了。。。2000MS+了。。。

然后就学了一下矩阵的优化。。。优化后。。。60MS。。orz。。。

一开始的代码:

View Code
 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 }

优化后的代码。。

View Code
 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 }

 

posted @ 2013-02-01 14:30  ihge2k  阅读(507)  评论(0编辑  收藏  举报