HDU

题目:

The Shortest Path

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1827    Accepted Submission(s): 589


Problem Description
There are N cities in the country. Each city is represent by a matrix size of M*M. If city A, B and C satisfy that A*B = C, we say that there is a road from A to C with distance 1 (but that does not means there is a road from C to A).
Now the king of the country wants to ask me some problems, in the format:
Is there is a road from city X to Y?
I have to answer the questions quickly, can you help me?
 
Input
Each test case contains a single integer N, M, indicating the number of cities in the country and the size of each city. The next following N blocks each block stands for a matrix size of M*M. Then a integer K means the number of questions the king will ask, the following K lines each contains two integers X, Y(1-based).The input is terminated by a set starting with N = M = 0. All integers are in the range [0, 80].
 
Output
For each test case, you should output one line for each question the king asked, if there is a road from city X to Y? Output the shortest distance from X to Y. If not, output "Sorry".
 
Sample Input
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
 
Sample Output
1
Sorry
 
  题意:给你n个m*m的矩阵,如果某个矩阵A*不是A的某个矩阵B=非A、B的矩阵C(这里的ABC只是编号上面的不一样),那么就说明A到C有一条有向边,长度为1,然后给你q个询问,求询问中X到Y的最短路,如果X到Y没有路,就输出Sorry。
  这一题的实质就是一个矩阵的乘法、矩阵的相等判定以及最短路,矩阵的乘法直接按照定义求,对于判定相等,可以直接逐个位置的元素判定是否相等也可以用memcmp()函数来判断,不过如果是用后者的话要注意空余的位置要在一开始赋值为0或者-1,总之就是排除干扰的因素,最短路这里用了Flyod。
  这一题难度其实不是很大,就是做的时候有点累,结果敲完代码以后交上去一直WA,后来检查代码才发现Flyod写好了但是没有调用= =。
  看来要注意合理休息。
 
代码:
 
  1 #include <cstdio>
  2 #include <cstring>
  3 #define INF 1000000000
  4 #define MAX 80
  5 using namespace std;
  6 
  7 int n,m,dis[MAX][MAX];
  8 
  9 typedef struct Mat
 10 {
 11     int city[MAX][MAX];
 12 
 13     void Init()
 14     {
 15         memset(city,0,sizeof(city));
 16     }
 17 
 18     void Insert()
 19     {
 20         int i,j;
 21         Init();
 22         for(i=0;i<m;i++)
 23         {
 24             for(j=0;j<m;j++)
 25             {
 26                 scanf("%d",&city[i][j]);
 27             }
 28         }
 29     }
 30 
 31     void print()
 32     {
 33         int i,j;
 34         for(i=0;i<m;i++)
 35         {
 36             for(j=0;j<m;j++)
 37             {
 38                 printf("%d ",city[i][j]);
 39             }
 40             printf("
");
 41         }
 42     }
 43 
 44     Mat operator * (const Mat &b)
 45     {
 46         int i,j,u;
 47         Mat c;
 48         c.Init();
 49         for(u=0;u<m;u++)
 50         {
 51             for(i=0;i<m;i++)
 52             {
 53                 if(!city[i][u]) continue;
 54                 for(j=0;j<m;j++)
 55                 {
 56                     c.city[i][j]+=city[i][u]*b.city[u][j];
 57                 }
 58             }
 59         }
 60         return c;
 61     }
 62 
 63     bool operator == (const Mat &b)
 64     {
 65         return (memcmp(city,b.city,sizeof(city))==0);
 66         /*
 67         int i,j;
 68         for(i=0;i<m;i++)
 69         {
 70             for(j=0;j<m;j++)
 71             {
 72                 if(city[i][j]!=b.city[i][j]) return 0;
 73             }
 74         }
 75         return 1;
 76         */
 77     }
 78 }Mat;
 79 
 80 Mat mat[1000];
 81 
 82 void Flyod()
 83 {
 84     int i,j,u;
 85     for(u=1;u<=n;u++)
 86     {
 87         for(i=1;i<=n;i++)
 88         {
 89             for(j=1;j<=n;j++)
 90             {
 91                 int len=dis[i][u]+dis[u][j];
 92                 if(dis[i][j]>len) dis[i][j]=len;
 93             }
 94         }
 95     }
 96 
 97 }
 98 
 99 int main()
100 {
101     int i,j,u,q,a,b;
102     //freopen("data.txt","r",stdin);
103     while(scanf("%d %d",&n,&m),(n+m))
104     {
105         for(i=1;i<=n;i++)
106         {
107             mat[i].Insert();
108             //mat[i].print();
109         }
110         for(i=1;i<=n;i++)
111         {
112             for(j=1;j<=n;j++)
113             {
114                 dis[i][j]= i==j ? 0 : INF;
115             }
116         }
117         for(i=1;i<=n;i++)
118         {
119             for(j=1;j<=n;j++)
120             {
121                 if(i==j) continue;
122                 Mat c=mat[i]*mat[j];
123                 for(u=1;u<=n;u++)
124                 {
125                     if(i==u || j==u) continue;
126                     if(c==mat[u]) dis[i][u]=1;
127                 }
128             }
129         }
130         Flyod();
131         scanf("%d",&q);
132         for(i=0;i<q;i++)
133         {
134             scanf("%d %d",&a,&b);
135             if(dis[a][b]<INF) printf("%d
",dis[a][b]);
136             else printf("Sorry
");
137         }
138     }
139     return 0;
140 }
2807
原文地址:https://www.cnblogs.com/sineatos/p/3306049.html