D - Silver Cow Party POJ - 3268——————最短路+思维(两遍单元最短路)

该博客介绍了如何解决POJ 3268问题,即'Silver Cow Party'。博主指出使用Floyd算法会导致超时,因此提出采用两遍单位最短路的方法来求解。博客详细阐述了这一策略并提供了相关代码。
题目连接

https://vjudge.net/contest/313997#problem/D

大体思路:

这个题用floyd 会T的
所以就要 这跑一边最短路, 着跑一边最短路

详细思路+代码
/******
题目要求: 是 询问 最快来回一趟, 耗时最大的那头牛所用的时间

两边单源最短路就行
①首先可以求出 从聚会点返回到牛棚的最短路径【这个你们都会】

②从牛棚去的时候的最短路径就是:
 可以看成 从聚会点沿着路 反向的最短路( u到v 的最短路 可以看成  v到u的 沿着路反向走的最短路径)



*******/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
const int maxn = 1e3+50;
const ll inf = 0x3f3f3f3f;
ll mp[maxn][maxn];
ll mp2[maxn][maxn];// 存反向图
int N, M, X;
void init()
{
    for(int i = 1;i <= N;i++)
    {
        for(int j = 1;j <= N;j++)
        {
            mp[i][j] = inf;
            mp2[i][j] = inf;
        }
    }
    for(int i = 1;i <= N;i++)
    {
        mp[i][i] = 0;
        mp2[i][i] = 0;
    }
}
void floyd()
{
    for(int k = 1;k <= N;k++)
        for(int i = 1;i <= N;i++)
            for(int j = 1;j <= N;j++)
                 if(mp[i][k]!= inf &&mp[j][k]!=inf&&mp[i][k]+mp[k][j] < mp[i][j])
                    mp[i][j] = mp[i][k]+mp[k][j];
}
void spfa(int s, ll mpx[][maxn])
{
    queue<int>q;//
    while(!q.empty())q.pop();//
    bool vis[maxn];//
    for(int i = 1;i <= N;i++)vis[i] = false;//

    ll dis[maxn];
    for(int i = 1;i <= N;i++)dis[i] = inf;//
    dis[s] = 0;//

    q.push(s);
    vis[s] = true;

    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(int i = 1;i <= N;i++)
        {

            if(dis[i] > dis[u]+mpx[u][i])
            {
                dis[i] = dis[u]+mpx[u][i];
                if(!vis[i])
                {
                    q.push(i);
                    vis[i] = true;
                }
            }
        }

    }

    for(int i = 1;i <= N;i++)
    {
        mpx[s][i] = dis[i];
    }


}
int main()
{

    scanf("%lld %lld %lld", &N, &M, &X);
    init();

    while(M--)
    {
        ll u, v, w;
        scanf("%lld %lld %lld", &u, &v, &w);
        if(w < mp[u][v])mp[u][v] = w;// 图
        if(w < mp2[v][u])mp2[v][u] = w;// 反向图
    }
    spfa(X, mp);
    spfa(X, mp2);
    ll ans = 0;
    for(int i = 1;i <= N;i++)
    {
        ans = max(ans, mp[X][i]+mp2[X][i]);
    }
    printf("%lld", ans);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值