题目地址: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; }
HDU 2833 WuKong(floyd最短路),布布扣,bubuko.com
原文地址:http://blog.csdn.net/scf0920/article/details/38345431