HLG 1040 Mining【Dijkstra】

题目大意:给出一个图,矿场位置,zfy和kevin的寝室位置,zfy和kevin一起从矿场回寝室,要求他们两人回寝室的最短路径,而且,在保证他们两人都是走的最短路径的同时,还要保证他们两个人一起走的距离尽可能的多。

 解题报告:
以下图为例,3到1的最短路为23,3到2的最短路径为24,他们先从3走到5,然后各自回家,能保证都是走的最短路径,同时也能一起走20的距离
 
首先,必须求出矿场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;
}

 

 
posted @ 2012-07-21 00:45  'wind  阅读(204)  评论(0编辑  收藏  举报