POJ Silver Cow Party【最短路】
题意: 有 N 头牛位于N个地点,知道了M 条边,这些牛现在要去 x 号牛那里聚会,问这些牛从自己的地点出发到 x 点,再回到自己的地点的所有最短路径中最长的一条,
而且来的时候的路和回去的路不能相同,(因为边是单向的,肯定不同)。
分析: 题意即将每头牛到 x 点的最短距离和该牛回来的最短距离相加,找出其中的最大距离。
如果以每个点为起点 ,以 x 为终点 求最短路,再加上以 x 为起点以每个牛的地点为终点的距离的话,容易超时,
可以在先求出 以 x 点为起点以各个点为终点的最小距离之后,将原图的边反转,这样以 x 为起点以其他各个点为终点的最短距离,即为以每个点为起点以 x 为终点的
的最短距离。
#include<stdio.h> #include<string.h> #include<queue> #define INF 0x1f1f1f1f #define clr(x)memset(x,0,sizeof(x)) int g[1003][1003]; int d1[1003]; int d2[1003]; int n; void dijkstra(int st,int d[]) { int s[1002]; int u,tmp,i,j; clr(s); for(i=1;i<=n;i++) d[i]=g[st][i]; d[st]=0; d[st]=1; for(i=1;i<n;i++) { tmp=INF; u=st; for(j=1;j<=n;j++) if(!s[j]&&d[j]<tmp) { tmp=d[j]; u=j; } s[u]=1; for(j=1;j<=n;j++) if(!s[j]&&g[u][j]!=INF&&d[u]+g[u][j]<d[j]) d[j]=d[u]+g[u][j]; } } int main() { int x,i,j,t,m,a,b,c,res; while(scanf("%d%d%d",&n,&m,&x)!=EOF) { memset(g,INF,sizeof(g)); res=-1; while(m--) { scanf("%d%d%d",&a,&b,&c); g[a][b]=c; } memset(d1,INF,sizeof(d1)); memset(d2,INF,sizeof(d2)); dijkstra(x,d1); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) { t=g[i][j]; g[i][j]=g[j][i]; g[j][i]=t; } dijkstra(x,d2); for(i=1;i<=n;i++) { if(i==x) continue; if(d1[i]+d2[i]>res) res=d1[i]+d2[i]; } printf("%d\n",res); } return 0; }