题目地址:HDU 2833
这题想到了最后是通过dis[s][t]==dis[s][i]+dis[i][j]+dis[j][t]的思路来判定是否属于最短路的一条。。但是没想到可以用floyd来找最短路中的点数。。。最短路还是太渣了。。好多性质都不会利用。。
这题的思路就是通过floyd对每两个点之间的最短路条数进行计数,然后通过上面的公式(对两条路线均要判定,都符合才说明都可以走),再找最短路中的最大点数。
代码如下:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <queue>
#include <map>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
int dp[400][400], num[400][400], n, s1, t1, s2, t2;
void floyd()
{
int i, j, k;
for(k=1; k<=n; k++)
{
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(dp[i][j]>dp[i][k]+dp[k][j])
{
dp[i][j]=dp[i][k]+dp[k][j];
num[i][j]=num[i][k]+num[k][j];
}
else if(dp[i][j]==dp[i][k]+dp[k][j])
{
if(num[i][j]<num[i][k]+num[k][j])
{
num[i][j]=num[i][k]+num[k][j];
}
}
}
}
}
}
int main()
{
int m, u, v, i, j, w, max1;
while(scanf("%d%d",&n,&m)!=EOF&&n&&m)
{
memset(dp,INF,sizeof(dp));
memset(num,0,sizeof(num));
for(i=1;i<=n;i++)
{
dp[i][i]=0;
}
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
if(dp[u][v]>w)
{
dp[u][v]=w;
dp[v][u]=w;
num[u][v]=1;
num[v][u]=1;
}
}
scanf("%d%d%d%d",&s1,&t1,&s2,&t2);
floyd();
max1=-1;
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
if(dp[s1][t1]==dp[s1][i]+dp[i][j]+dp[j][t1]&&dp[s2][t2]==dp[s2][i]+dp[i][j]+dp[j][t2])
{
if(max1<num[i][j])
{
max1=num[i][j];
}
}
}
}
printf("%d\n",max1+1);
}
return 0;
}