hdu 2807 The Shortest Path(矩阵)

The Shortest Path

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


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
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   2224  1217  2803  2802  2544 
 

Statistic |  Submit |  Discuss | Note

题解:根据题意乱搞即可。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 83
#define inf 1000000000
using namespace std;
int n,m,dis[N][N];
struct data
{
	int a[N][N];
}point[N];
data get(data a,data b)
{
	data c;
	for (int i=1;i<=m;i++)
	 for (int j=1;j<=m;j++)
	  {
	  	c.a[i][j]=0;
	  	for (int k=1;k<=m;k++)
	  	 c.a[i][j]=c.a[i][j]+a.a[i][k]*b.a[k][j];
	  }
	return c;
}
bool pd(data a,data b)
{
	for (int i=1;i<=m;i++)
	 for (int j=1;j<=m;j++)
	  if (a.a[i][j]!=b.a[i][j])  return 0;
	return 1;
}
void calc()
{
	for (int a=1;a<=n;a++)
	 for  (int b=1;b<=n;b++)
	  if (a!=b)
	  {
	  	data t=get(point[a],point[b]);
	  	for (int c=1;c<=n;c++)
	  	 {
	  	 	if (c==a||c==b) continue;
	  	 	if  (pd(point[c],t))  dis[a][c]=1;
	  	 }
	  }
}
void floyed()
{
	for (int k=1;k<=n;k++)
	 for (int i=1;i<=n;i++)
	  if (dis[i][k]!=inf)
	  for (int j=1;j<=n;j++)
	   if (dis[k][j]!=inf)
	    if (k!=i&&i!=j&&j!=k)
	     dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int main()
{
	while (scanf("%d%d",&n,&m)!=EOF)
	{
		if (!n&&!m)  break;
		for (int i=1;i<=n;i++)
		 {
		 	for (int j=1;j<=m;j++)
		 	 for (int k=1;k<=m;k++)
		 	  scanf("%d",&point[i].a[j][k]);
		 }
		for (int i=1;i<=n;i++)
		 for (int j=1;j<=n;j++)
		  dis[i][j]=inf;
		calc();
		floyed();
		int t; scanf("%d",&t);
		for (int i=1;i<=t;i++)
		{
			int x,y; scanf("%d%d",&x,&y);
			if (dis[x][y]!=inf)  printf("%d\n",dis[x][y]);
			else printf("Sorry\n");
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值