Silver Cow Party

本文介绍了一个关于寻找最优路径的问题,具体为多个农场中每只奶牛到特定农场参加聚会并返回的最短时间问题。通过两次Dijkstra算法计算往返所需的最大时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Silver Cow Party

One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requiresTi (1 ≤ Ti ≤ 100) units of time to traverse.

Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.

Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?

Line 1: Three space-separated integers, respectively: N, M, and X 
Lines 2.. M+1: Line i+1 describes road i with three space-separated integers: Ai,Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Line 1: One integer: the maximum of time any one cow must walk.
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

题目大意:有n个农场,从每个农场出来一只奶牛到第x个农场参加聚会,参加完聚会后返回,每条路是单向的,所以不能原路返回,问每头奶牛需要的时间中的最长时间;

思路:起点不一样,终点一样,所以从终点开始找到每个农场的最短路,因为是从起点到终点,所有要把路径反向;两次dijkstra后,算出来回需要的最大值;

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f3f
#define ll long long
using namespace std;
int e[1005][1005];//用来储存正向路径
int ee[1005][1005];//用来储存反向路径
int mark[1005];
int dis[1005],ds[1005];

int main()
{
    int n,m,x;
    while(~scanf("%d %d %d",&n,&m,&x))//n个农场,m条路,到x农场开聚会
    {
        memset(e,0,sizeof(e));
        memset(ee,0,sizeof(ee));
        memset(dis,0,sizeof(dis));
        memset(ds,0,sizeof(ds));
        memset(mark,0,sizeof(mark));
        int a,b,l,i,j;
        for(i=1; i<=n; i++)
            for(j=1; j<=n; j++)
                if(i==j)
                {
                    e[i][j]=0;
                    ee[i][j]=0;
                }
                else
                {
                    e[i][j]=inf;
                    ee[i][j]=inf;
                }
        for(i=1; i<=m; i++)
        {
            scanf("%d %d %d",&a,&b,&l);
            e[a][b]=min(e[a][b],l);
            ee[b][a]=min(ee[b][a],l);
        }
        int pos=x,s=0;
        for(i=1;i<=n;i++)
            ds[i]=ee[pos][i];
        mark[pos]=1;
        for(i=1; i<n; i++)
        {
            int mini=inf;
            for(j=1; j<=n; j++)
            {
                if(mark[j]==0&&ds[j]<mini)
                {
                    pos=j;
                    mini=ds[j];
                }
            }
            mark[pos]=1;
            for(j=1; j<=n; j++)
            {
                if(mark[j]==0&&ds[j]>ds[pos]+ee[pos][j])
                    ds[j]=ee[pos][j]+ds[pos];
            }
        }
        pos=x;
        memset(mark,0,sizeof(mark));
        mark[pos]=1;
        for(i=1; i<=n; i++)
            dis[i]=e[pos][i];
        for(i=1; i<n; i++)
        {
            int mini=inf;
            for(j=1; j<=n; j++)
            {
                if(mark[j]==0&&dis[j]<mini)
                {
                    pos=j;
                    mini=dis[j];
                }
            }
            mark[pos]=1;
            for(j=1; j<=n; j++)
            {
                if(mark[j]==0&&dis[j]>e[pos][j]+dis[pos])
                    dis[j]=e[pos][j]+dis[pos];
            }
        }
        for(i=1;i<=n;i++)
        {
            if(ds[i]+dis[i]>s)
                s=dis[i]+ds[i];
        }
        printf("%d\n",s);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值