题目链接
题意:求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;
}