题目描述
小z放假了,准备到RRR城市旅行,其中这个城市有N个旅游景点。小z时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍RRR城。
小z很开心,直接就把钱一次性缴足了。然而小z心机很重,他想选择的路程尽量长。
然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。
你能帮帮小z吗?
需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复)
输入描述:
本题包含多组输入,第一行输入一个整数t,表示测试数据的组数
每组测试数据第一行输入两个数N,M表示RRR城一共有的旅游景点的数量,以及RRR城中有的路的数量。
接下来M行,每行三个数,a,b,c表示从a景点和b景点之间有一条长为c的路
输出描述:
每组数据输出两行,
每组数据包含一行,输出一个数,表示整条路程的路长。
如果找不到可行解,输出-1.
思路:
每次选一个点作为中间点,然后跑一边单源最短路,记录距离最远的两个点的距离和,答案就是最大的和,复杂度n n
logn
附代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 5;
const int INF = 0x3f3f3f3f;
int n,m,s,t;
struct edge{int v,w;edge(int x,int y){v=x,w=y;}};
vector<edge>v[N];
int vis[N],dis[N];
struct node{
int num,dis;
node(int x,int y){num=x,dis=y;};
friend bool operator >(const node &a,const node &b){return a.dis>b.dis;}
};
void add(int x,int y,int z){
v[x].push_back(edge(y,z));
}
ll Dig(int s){
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
priority_queue<node,vector<node> ,greater<node> >q;
q.push(node(s,0));
int x=0,y=0;
while(!q.empty()){
node now=q.top();
q.pop();
int u=now.num;
if(vis[u])continue;
y=max(y,dis[u]);
if(y>x)swap(x,y);
vis[u]=1;
for(int i=0;i<v[u].size();i++){
edge next=v[u][i];
if(vis[next.v])continue;
if(dis[u]+next.w<dis[next.v]){
dis[next.v]=dis[u]+next.w;
q.push(node(next.v,dis[next.v]));
}
}
}
if(!y)return 0;
return (x+y);
}
void solve(){
memset(v,0,sizeof(v));
ll ans=0;
cin>>n>>m;
int x,y,z;
for(int i=0;i<m;i++)
cin>>x>>y>>z,add(x,y,z),add(y,x,z);
for(int i=1;i<=n;i++){
ans=max(Dig(i),ans);
}
if(!ans)ans=-1;
cout<<ans<<'\n';
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int t;cin>>t;
while(t--)solve();
}



京公网安备 11010502036488号