hdu 2807 The Shortest Path【暴力/矩阵判等优化+Floyd】
来源:互联网 发布:佛山市禅城区广电网络 编辑:程序博客网 时间:2024/09/21 11:23
The Shortest Path
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3042 Accepted Submission(s): 995
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
Source
HDU 2009-4 Programming Contest
题目大意:有N个矩阵,每个矩阵的规格都是M*M那么大,如果满足有矩阵A*B==C那么说明节点A到节点C有一条有向边。 对于那么些个询问,如果这两个节点之间有路想通,输出最小路径,否则输出Sorry。
思路:
1、对于之后询问部分的操作,每次询问都做一次单源最短路显然是有点多余的,而且N最大也就80,我们不妨在这里求最短路的时候使用Floyd算法求其最短路,这样对于每个查询直接输出即可。
2、对于这个题来说,最难受的一个点就是如果两层for枚举I,J点对,然后求其矩阵乘法,然后再从其他矩阵里边找是否和当前乘法之后求得的矩阵相等,显然最差需要N^2*M^3来做这个题。如果N,M都是80的话,显然会超时,但是捏,后台数据一定是放宽了条件,暴力代码AC了0.0.
这里先上一下暴力AC代码:
1200+ms
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;typedef struct Matrix{ int mat[85][85];} matrix;int n,m;int map[85][85];matrix a[85];int min(int a,int b){ if(a>b)return b; else return a;}Matrix matrix_mul(matrix a,matrix b){ matrix c; memset(c.mat,0,sizeof(c.mat)); int i,j,k; for(int i=0; i<m; i++) { for(int j=0; j<m; j++) { for(int k=0; k<m; k++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; } } } return c;}int judge(matrix a,matrix b){ for(int i=0; i<m; i++) { for(int j=0; j<m; j++) { if(a.mat[i][j]!=b.mat[i][j])return 0; } } return 1;}void Floyd(){ for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { for(int k=0; k<n; k++) { map[j][k]=min(map[j][k],map[j][i]+map[i][k]); } } }}void getmap(){ for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { if(i==j)continue; matrix tmp; tmp=matrix_mul(a[i],a[j]); for(int k=0; k<n; k++) { if(k==i||k==j)continue; if(judge(tmp,a[k])==1) { map[i][k]=1; } } } }}int main(){ while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { for(int k=0; k<m; k++) { scanf("%d",&a[i].mat[j][k]); } } } for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { map[i][j]=0x3f3f3f3f; } } getmap(); Floyd(); int q; scanf("%d",&q); while(q--) { int x,y; scanf("%d%d",&x,&y); x--; y--; if(map[x][y]<0x3f3f3f3f) { printf("%d\n",map[x][y]); } else printf("Sorry\n"); } } return 0;}
3、在这里,其实我们可以对于矩阵判等进行优化。我们知道,如果直接求当前题情况下两个矩阵的乘法,那么需要M^3来计算这个乘法之后的矩阵,其实我们不妨这样来优化:
假设我们要判断:A*B==C,我们其实可以这样加以判断:D*A*B==D*C;可能读者一下子笑了,这尼玛能优化?明明增加了乘法操作好伐。其实不然,如果D也是M*M规格的,显然是多余了,不过假如我们让D的规模是1*M,这样显然需要的操作是1*M*M+1*M*M*1*M*M。实现了优化,并没有增加乘法的操作。
优化算法之后的AC代码:
400+ms
#include<stdio.h>#include<string.h>#include<iostream>using namespace std;typedef struct Matrix{ int mat[85][85];} matrix;int n,m;int map[85][85];matrix a[85];void Floyd(){ for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { for(int k=0; k<n; k++) { map[j][k]=min(map[j][k],map[j][i]+map[i][k]); } } }}void getmap(){ int tmp[85]; int tmp2[85]; int c[85]; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i==j)continue; for(int k=0;k<m;k++)tmp[k]=0; for(int k=0;k<m;k++)c[k]=0; for(int k=0;k<m;k++) { for(int l=0;l<m;l++) { tmp[k]+=1*a[i].mat[k][l]; } } for(int k=0;k<m;k++) { for(int l=0;l<m;l++) { c[k]+=tmp[k]*a[j].mat[k][l]; } } for(int k=0;k<n;k++) { if(k==i||k==j)continue; for(int x=0;x<m;x++)tmp2[x]=0; for(int x=0;x<m;x++) { for(int y=0;y<m;y++) { tmp2[x]+=1*a[k].mat[x][y]; } } int flag=1; for(int x=0;x<m;x++) { if(c[x]!=tmp2[x]) flag=0; } if(flag==1) { map[i][k]=1; } } } }}int main(){ while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { for(int k=0; k<m; k++) { scanf("%d",&a[i].mat[j][k]); } } } for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { map[i][j]=0x3f3f3f3f; } } getmap(); Floyd(); int q; scanf("%d",&q); while(q--) { int x,y; scanf("%d%d",&x,&y); x--; y--; if(map[x][y]<0x3f3f3f3f) { printf("%d\n",map[x][y]); } else printf("Sorry\n"); } } return 0;}
- hdu 2807 The Shortest Path【暴力/矩阵判等优化+Floyd】
- hdu 2807 The Shortest Path 优化矩阵运算+floyd
- hdu 2807 The Shortest Path(矩阵相乘+floyd)
- HDU 2807 The Shortest Path(矩阵相乘+Floyd)
- HDU - 2807The Shortest Path(矩阵相乘+Floyd)
- hdu 2807 The Shortest Path(矩阵计算+Floyd)
- Hdu 2807 The Shortest Path 矩阵相乘
- hdu 2807 The Shortest Path(矩阵)
- HDU 2807 The Shortest Path 把矩阵抽象成点+Floyd
- HDU2807:The Shortest Path(矩阵乘法+快速矩阵比较+Floyd)
- HDU 2807 The Shortest Path 矩阵运算+最短路
- hdu 2807 The Shortest Path
- hdu 2807 The Shortest Path
- hdu 2807 The Shortest Path
- HDU 2807 The Shortest Path
- HDU 2807 The Shortest Path
- HDU 2807 The Shortest Path
- HDU-2807-The Shortest Path
- 项目开始前明确3件事
- UIKit: UIControl
- 非零环绕数规则和奇-偶规则(Non-Zero Winding Number Rule&&Odd-even Rule)
- [Python]zeromq:socket request/receive, 发布/订阅消息, 进程间通讯
- Hammer.js
- hdu 2807 The Shortest Path【暴力/矩阵判等优化+Floyd】
- 数据类型
- Attempt to set a non-property-list object 报错问题
- 把字符串的大写字母放到字符串的后面
- windows Ubuntu双系统引导修复
- Could not enlist in transaction on entering meta-aware object
- springmvc研究
- GET/POST
- Mongo DB安装及配置