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;
}

 

posted @ 2012-08-10 20:22  'wind  阅读(143)  评论(0编辑  收藏  举报