牛客 B-旅行(最短路)(dijkstra算法)
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客 B-旅行(最短路)(dijkstra算法)相关的知识,希望对你有一定的参考价值。
B-旅行
思路:
要保证必须经过三个旅游景点一个作为起点,一个作为中转点,一个作为终点
所以只要枚举中转点就行了,以该中转点为起点进行dijkstra,只要存在最短距离的点数大于等于三,找其中最大的两个距离相加,就是最短距离的最大路径长度。
#include<bits/stdc++.h>
using namespace std;
#define se second
#define fi first
typedef long long ll;
typedef pair<int ,int> pii;
const int inf = 0x3f3f3f3f;
const int N = 1e3+5;
const int M = 1e3+5;
//存边
struct edge
{
int to,w;
edge(int a,int b)
{
to = a;w = b;
}
};
vector<edge>e[M];
int n,m;
//最短距离 具有最短距离点的距离
ll dis[N],ans[N],res=-1;
void dijkstra(int x)
{
//先初始化最短距离为无限大
for(int i=1;i<=n;i++) dis[i]=inf;
dis[x] = 0; //起点的最短距离为0
priority_queue<pii>q;
q.push({0,x});//起点入队列 {最短距离,节点号}
while(!q.empty())
{
pii p = q.top();
q.pop();
for(int i=0;i<e[p.se].size();i++)
{
int t = e[p.se][i].to;//边的的指向
if(dis[t] > dis[p.se] + e[p.se][i].w)//判断距离
{
dis[t] = dis[p.se] + e[p.se][i].w;
q.push({-dis[t],t});
//把距离的负值入队,因为优先队列存pair是从大到小存的,要想距离从小到大排列,把距离变为负值
}
}
}
int cnt = 0;
for(int i=1;i<=n;i++)
{//如果最短距离不是初始化的距离,说明有最短距离,存起来
if(dis[i]!=inf)
ans[++cnt] = dis[i];
}
//如果有最短距离的节点数大于2,说明至少有三个节点,可以选择三个旅游地,处理答案
if(cnt > 2)
{
sort(ans+1,ans+1+cnt);
res = max(res,ans[cnt]+ans[cnt-1]);
}
}
void solve()
{
cin>>n>>m;
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<=m;i++)
{
int a,b,c;
cin>>a>>b>>c;
e[a].push_back(edge(b,c));
e[b].push_back(edge(a,c));
}
res = -1;
//对每个中转点进行dijkstra
for(int i=1;i<=n;i++)
dijkstra(i);
cout<<res<<"\\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int _;cin>>_;
while(_--)
solve();
return 0;
}
以上是关于牛客 B-旅行(最短路)(dijkstra算法)的主要内容,如果未能解决你的问题,请参考以下文章
Codevs1041&&Vijos1119 car的旅行路线(最短路dijkstra)