HDU2833 WuKong Floyd

/*
Floyd的应用
用Floyd求出任意两点间的最短路径
两个定理:
1.所求的路径一定是一断连续的路径
2.如果路径(x,y)是a->b的最短路径中的一段,则min(a,b) = min(a,x) + min(x,y) + min(y,b)
最后只需找到同时在两条最短路径上,且距离最长的那一段
*/
#include <iostream>
using namespace std;

const int inf=200000000; 
int s[305][305];//记录最短路的长度
int num[305][305];//同样长度的最短路的最长的跳数

int main()
{
	int n, m, i, j, k, a, b, c, d, ans, start, end, dis;
	while(scanf("%d%d", &n, &m), m || n)
	{
		memset(num, 0, sizeof(num));
		for(i = 0; i <= n; i++)
		{  
            for(j = 0; j <= n; j++) 
                s[i][j]=(i==j)?0:inf;       
        }  
		for(i = 0; i < m; i++)
		{
			scanf("%d%d%d", &start, &end, &dis);
			if(s[start][end] < dis)
				continue;
			s[start][end] = dis;
			s[end][start] = dis;
			num[start][end] = 1;
			num[end][start] = 1;
		}
		for(k=1;k<=n;k++)
		{  
			for(i=1;i<=n;i++)
			{  
				for(j=1;j<=n;j++)
				{  
					if(s[i][j]>s[i][k]+s[k][j])
					{
						s[i][j]=s[i][k]+s[k][j];
						num[i][j] = num[i][k] + num[k][j];
					}
					else if (s[i][j] == s[i][k] + s[k][j] && num[i][j] < num[i][k] + num[k][j])
						num[i][j] = num[i][k] + num[k][j];
				}     
			}     
		}
		scanf("%d%d%d%d", &a, &b, &c, &d);
		ans = -1;
		for(i = 1; i <= n; i++)
		{
			for(j = 1; j <= n; j++)
			{
				if(num[i][j] > ans && (s[a][b] == s[a][i] + s[i][j] + s[j][b]) && (s[c][d] == s[c][i] + s[i][j] + s[j][d]))
					ans = num[i][j];
			}
		}
		printf("%d\n", ans + 1);
	}
	return 0;
}

你可能感兴趣的:(HDU2833 WuKong Floyd)