[HDU2833] [2009多校联考2] WuKong [单源最短路]

题目链接
题意:求A~B最短路和C~D最短路的最大交点数量。
N<300。M<N*N。

i→j在两条最短路内当且仅当dis[A][i]+dis[i][j]+dis[j][B]=dis[A][B]
而且dis[C][i]+dis[i][j]+dis[j][D]=dis[C][D]
跑floyd然后N^2枚举,取最长连续公共路径。
答案就等于这个加一。为什么?
因为最长路径一定连续。(重边不考虑)
A→B,C→D里面的点i和j,它们之间的路径i→j一定是i到j的最短路。
所以要取到最多公共点当然要取连续路径啦

Accepted 1138B
187MS	 2100K
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<iostream>
using namespace std;
int N,M,A,B,C,D;
int ans;
int dis[305][305]={};
int len[305][305]={};
void floyd()
{
	for(int k=1;k<=N;++k)
		for(int i=1;i<=N;++i)
			for(int j=1;j<=N;++j)
				if((dis[i][j]>dis[i][k]+dis[k][j])||((dis[i][j]==dis[i][k]+dis[k][j])&&(len[i][k]+len[k][j]>len[i][j])))
					dis[i][j]=dis[i][k]+dis[k][j],
					len[i][j]=len[i][k]+len[k][j];
}
int main()
{
	while(~scanf("%d%d",&N,&M))
	{
		if(!N)break;
		ans=-1;
		memset(dis,0x3f,sizeof(dis));
		memset(len,0,sizeof(len));
		for(int a,b,c,i=1;i<=M;++i)
		{
			scanf("%d%d%d",&a,&b,&c);
			dis[a][b]=min(dis[a][b],c);
			dis[b][a]=min(dis[b][a],c);
			len[a][b]=len[b][a]=1;
		}
		for(int i=1;i<=N;++i)dis[i][i]=len[i][i]=0;
		floyd();
		scanf("%d%d%d%d",&A,&B,&C,&D);
		for(int i=1;i<=N;++i)
		for(int j=1;j<=N;++j)
			if(len[i][j]>ans)
			if(dis[A][i]+dis[i][j]+dis[j][B]==dis[A][B])
			if(dis[C][i]+dis[i][j]+dis[j][D]==dis[C][D])
				ans=len[i][j];
				
		printf("%d\n",ans+1);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值