zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    升级windows 11小工具
    windows 10更新升级方法
    您需要了解的有关 Oracle 数据库修补的所有信息
    Step by Step Apply Rolling PSU Patch In Oracle Database 12c RAC Environment
    Upgrade Oracle Database Manually from 12.2.0.1 to 19c
    如何应用版本更新 12.2.0.1.210420(补丁 32507738 – 2021 年 4 月 RU)
    xtrabackup 安装、备份和恢复
    Centos_Lvm expand capacity without restarting CentOS
    Centos_Lvm_Create pv vg lv and mount
    通过全备+relaylog同步恢复被drop的库或表
  • 原文地址:https://www.cnblogs.com/wally/p/2888968.html
Copyright © 2011-2022 走看看