POJ 3268 Silver Cow Party (最短路,思维)

N个农场(1≤N≤1000)各有一头奶牛,方便地编号为1.N,准备参加在农场#X(1≤X≤N)举行的大型奶牛聚会。
总共有M(1≤M≤100,000)个单向(单向道路)连接成对的农场;道路I需要Ti(1≤Ti≤100)个单位的时间来遍历。
每头牛都必须步行去参加聚会,当聚会结束后,回到自己的农场。
每头牛都很懒,因此选择了一条时间最短的最优路线。
由于道路是单向的,因此奶牛的返回路线可能不同于她去聚会的原始路线。
在所有的奶牛中,一头奶牛必须步行去聚会和回来的最长时间是多少?
输入。
第1行:三个空格分隔的整数,分别为:N、M和X。
第2行.。
M+1:行I+1用三个空格分隔的整数描述道路I:AI、Bi和Ti。
描述的道路从农场AI到农场Bi,需要Ti时间单位来穿越。
输出量。
第1行:一个整数:任何一头奶牛必须行走的最长时间。
Sample Input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
Sample Output
10
Hint

关键在于思维,直接做的话,迪杰斯特拉算法或者佛洛依德算法都一定超时,优化过的迪杰斯特拉算法也有可能超时。
首先,x到其他所有的点距离好求,而其他点到x的距离,如果把原图逆过来 map[i][j]=map[j][i],再求x到其他所有的点距离,即为其他点到x的距离。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <string>

using namespace std;

int mapp[1010][1010],mapp0[1010][1010];
int temp[1010],temp0[1010],flg[1010];
int main()
{

    int i,j,k,x,l,n,m,maxx,mark;

    scanf("%d%d%d",&n,&m,&x);

    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    {
        if(i!=j)
        {
            mapp[i][j]=1061109567;
            mapp0[i][j]=1061109567;
        }

    }

    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&j,&k,&l);
        if(mapp[j][k]>l)
        mapp[j][k]=l;

        if(mapp0[k][j]>l)
        mapp0[k][j]=l;

    }



    for(j=1;j<=n;j++)
    temp[j]=mapp[x][j];

    flg[x]=1;
    for(j=1;j<n;j++)
    {
        maxx=1061109567;
        mark=x;
        for(i=1;i<=n;i++)
        {
            if(flg[i]==0&&temp[i]<maxx)
            {
                maxx=temp[i];
                mark=i;
            }
        }
        flg[mark]=1;

        for(i=1;i<=n;i++)
        {
            if(temp[i]>temp[mark]+mapp[mark][i])
                temp[i]=temp[mark]+mapp[mark][i];
        }

    }




    for(i=1;i<=n;i++)
    flg[i]=0;


    for(j=1;j<=n;j++)
    temp0[j]=mapp0[x][j];

    flg[x]=1;
    for(j=1;j<n;j++)
    {
        maxx=1061109567;
        mark=x;
        for(i=1;i<=n;i++)
        {
            if(flg[i]==0&&temp0[i]<maxx)
            {
                maxx=temp0[i];
                mark=i;
            }
        }
        flg[mark]=1;

        for(i=1;i<=n;i++)
        {
            if(temp0[i]>temp0[mark]+mapp0[mark][i])
                temp0[i]=temp0[mark]+mapp0[mark][i];
        }

    }



    maxx=0;
    for(i=1;i<=n;i++)
    {
        if(maxx<temp0[i]+temp[i])
        maxx=temp0[i]+temp[i];
    }

    printf("%d",maxx);

    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值