TZOJ 1693:银牛派对(最短路/dijstra)

描述

 

N个农场(1 ≤ N ≤ 1000)中的每一个都有一头奶牛,编号为 1.. N将参加在农场 # X(1 ≤ X ≤ N)举行的大型奶牛聚会。总共有M (1 ≤ M ≤ 100,000) 条单向(单向道路连接成对的农场;道路i需要i (1 ≤ i ≤ 100) 单位时间才能穿过。

每头奶牛必须步行去参加聚会,聚会结束后,回到她的农场。每头奶牛都很懒惰,因此会选择最短时间的最佳路线。由于道路是单向的,母牛的返回路线可能与她前往派对的原始路线不同。

在所有奶牛中,一头奶牛必须花多长时间去参加聚会和回来?

 

输入

第 1 行:三个空格分隔的整数,分别为:NMX
第 2 行.. M +1:第i +1 行用三个空格分隔的整数描述道路i : iii所描述的道路从农场i延伸到农场i,需要i个时间单位来穿越。

输出

第 1 行:一个整数:任何一头牛必须行走的最长时间。

样例输入

 

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

样例输出

 10

提示

奶牛 4 直接前往派对(3 个单位)并通过农场 1 和 3(7 个单位)返回,总共 10 个时间单位。
一开始想着是从起点到x算一遍再加上x到起点算一遍加起来,然后果不其然,TLE了。。去洛谷对了一下是有两个样例TLE了,还不错哈哈,然后看了看网上的解决方案是先计算起点到x得到一个dis最短路数组,然后将dis存储到另一个数组way上,再将原地图转置,继续算一遍dijstra就好了,结尾把dis和way的数值加起来比较每个点的最大值即可
复制代码
#include<bits/stdc++.h>
using namespace std;
const int inf = 1e8+10;
int ma[1005][1005];
int vis[1005];
int dis[1005],way[1005];
int n,m,x;
void dijstra(int sx)
{
    int pos=1,minn,sum=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)dis[i] = ma[sx][i];
    vis[sx] = 1;
    dis[sx] = 0;
    for(int i=1;i<=n;i++)
    {
        minn = inf;
        for(int j=1;j<=n;j++)
        {
            if(vis[j]==0&&minn>dis[j])
            {
                minn = dis[j];
                pos = j;
            }
        }
        if(minn==inf)break;
        vis[pos] = 1;
        for(int j=1;j<=n;j++)
        {
            if(vis[j]==0&&dis[j]>minn+ma[pos][j])
            {
                dis[j] = minn+ma[pos][j];
            }
        }
    }
}
int main()
{
    cin>>n>>m>>x;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            if(i==j)ma[i][j] = 0;
            else ma[i][j] = inf;
        }
    for(int i=1;i<=m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        if(ma[a][b]>c) ma[a][b] = c;
    }
    dijstra(x); //先计算每个点到x的最短路 
    for(int i=1;i<=n;i++)way[i] = dis[i]; //把到x的最短路记录到way中 
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        {
            swap(ma[i][j],ma[j][i]);//逆置矩阵,就可以将单向图逆转 
        }
    dijstra(x);//这里就相当于是计算x到各个点的最短路 
    int ans = -1;
    for(int i=1;i<=n;i++)
    {
        ans = max(way[i]+dis[i],ans);
    }
    cout<<ans;
     return 0;
}
复制代码

 

posted @   CRt0729  阅读(42)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示