HLG 1040 Mining【Dijkstra】
题目大意:给出一个图,矿场位置,zfy和kevin的寝室位置,zfy和kevin一起从矿场回寝室,要求他们两人回寝室的最短路径,而且,在保证他们两人都是走的最短路径的同时,还要保证他们两个人一起走的距离尽可能的多。
解题报告:
以下图为例,3到1的最短路为23,3到2的最短路径为24,他们先从3走到5,然后各自回家,能保证都是走的最短路径,同时也能一起走20的距离
![](https://pic002.cnblogs.com/images/2012/354995/2012072100434231.jpg)
首先,必须求出矿场B到各个点的最短路径,求出C到各个点的最短路径,再求出N到各个点的最短路径。我们用D[i][j]表示i到j之间的最短距离
使用三次DIJKSTRA算法即可完成
然后我们枚举zfy和kevin的分离点,枚举出了B, C, N之外的每一个点i
如果此时,D[B][i] + D[N][i] = D[B][N]而且D[B][i] + D[C][i] = D[B][C],说明这个i点是可以满足最短路径需求的分离点,在所有满足条件的i点中,取D[B][i]最大的,就是答案。
#include<stdio.h> #include<string.h> #define maxint 9999999999 int d[1002][1002]; void dijkstra(int n,int v,int *dist) { int s[1002]; int i,j,tmp,u,newdist; memset(s,0,sizeof(s)); for(i=1;i<=n;i++) { dist[i]=d[v][i]; s[i]=0; } dist[v]=0; s[v]=1; for(i=2;i<=n;i++) { tmp=maxint; u=v; for(j=1;j<=n;j++) if(!s[j]&&dist[j]<tmp) { u=j; tmp=dist[j]; } s[u]=1; for(j=1;j<=n;j++) if(!s[j]&&d[u][j]<maxint) { newdist=dist[u]+d[u][j]; if(newdist<dist[j]) { dist[j]=newdist; } } } for(i=1;i<=n;i++) d[v][i]=dist[i]; } int main() { int dist[1002]; int t,B,C,N,n,m,i,j,len,p,q,max,k1,k2; scanf("%d",&t); while(t--) { scanf("%d%d%d%d%d",&n,&B,&C,&N,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++) d[i][j]=maxint; while(m--) { scanf("%d%d%d",&p,&q,&len); if(len<d[p][q]) { d[p][q]=len; d[q][p]=len; } } for(i=1;i<=n;i++) dist[i]=maxint; dijkstra(n,B,dist); for(i=1;i<=n;i++) dist[i]=maxint; dijkstra(n,C,dist); for(i=1;i<=n;i++) dist[i]=maxint; dijkstra(n,N,dist); max=-999999; for(i=1;i<=n;i++) { if((d[B][i]+d[C][i]==d[B][C])&&(d[B][i]+d[N][i]==d[B][N])) if(d[B][i]>max) { k1=d[C][i]; k2=d[N][i]; max=d[B][i]; } } printf("%d %d %d\n",max,k1,k2); } return 0; }