POJ 3268 Silver Cow Party (最短路径)

本文解析了POJ3268题目,介绍了一种利用SPFA算法解决有向图中最短路径问题的方法,即计算所有点到指定点再返回的最短路径中的最大值。

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

POJ 3268 Silver Cow Party (最短路径)

Description

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 requires Ti (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?

Input

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.

Output

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

Http

POJ:https://vjudge.net/problem/POJ-3268

Source

最短路径

题目大意

在一个有向图中,求所有点都走到一个点再走回来的最短距离中的最大值

解决思路

我们知道单源最短路的求法,即从一个点走到其他点,那么我们只要把有向图中的边反过来求一遍就是从其他点走到一个点的最短距离
这里我们用spfa解决

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

const int maxN=1001;
const int inf=2147483647;

class Edge
{
public:
    int v,w;
};

int n,m,X;
vector<Edge> E1[maxN];
vector<Edge> E2[maxN];
queue<int> Q;
bool inqueue[maxN];
int Dist1[maxN];
int Dist2[maxN];

int main()
{
    scanf("%d%d%d",&n,&m,&X);
    for (int i=1;i<=m;i++)
    {
        int u,v,w;
        scanf("%d%d%D",&u,&v,&w);
        E1[u].push_back((Edge){v,w});//存正图
        E2[v].push_back((Edge){u,w});//存反图
    }
    memset(Dist1,127,sizeof(Dist1));//第一遍spfa
    memset(inqueue,0,sizeof(inqueue));
    Dist1[X]=0;
    inqueue[X]=1;
    while (!Q.empty())
        Q.pop();
    Q.push(X);
    do
    {
        int u=Q.front();
        Q.pop();
        inqueue[u]=0;
        for (int i=0;i<E1[u].size();i++)
        {
            int v=E1[u][i].v;
            int w=E1[u][i].w;
            if (Dist1[v]>Dist1[u]+w)
            {
                Dist1[v]=Dist1[u]+w;
                if (inqueue[v]==0)
                {
                    Q.push(v);
                    inqueue[v]=1;
                }
            }
        }
    }
    while (!Q.empty());
    memset(Dist2,127,sizeof(Dist2));//第二遍spfa
    memset(inqueue,0,sizeof(inqueue));
    Dist2[X]=0;
    inqueue[X]=1;
    Q.push(X);
    do
    {
        int u=Q.front();
        Q.pop();
        inqueue[u]=0;
        for (int i=0;i<E2[u].size();i++)
        {
            int v=E2[u][i].v;
            int w=E2[u][i].w;
            if (Dist2[v]>Dist2[u]+w)
            {
                Dist2[v]=Dist2[u]+w;
                if (inqueue[v]==0)
                {
                    Q.push(v);
                    inqueue[v]=1;
                }
            }
        }
    }
    while (!Q.empty());
    int Ans=0;
    for (int i=1;i<=n;i++)
        Ans=max(Ans,Dist1[i]+Dist2[i]);//统计最大值
    cout<<Ans<<endl;
    return 0;
}

转载于:https://www.cnblogs.com/SYCstudio/p/7225202.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值