题目大意:
小z放假了,准备到RRR城市旅行,其中这个城市有N个旅游景点。小z时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍RRR城。
小z很开心,直接就把钱一次性缴足了。然而小z心机很重,他想选择的路程尽量长。
然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。
你能帮帮小z吗?
需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复).
思路:因为数据很小,所以先进行一次暴力把两点间的最短路求出来,因为是稀疏图所以用spfa暴力。题目要求的是三个点两条边的最长,所以枚举中转点,以每个中转点为起点,再找出两条最长的边就是答案。
#include<bits/stdc++.h>
using namespace std;
const int maxm=1010;
const int maxn=1010;
const int inf=0x3f3f3f3f;
int head[maxn],vis[maxn][maxn],dis[maxn][maxn];
int cnt,n,m;
struct node
{
int to,next,l;
}e[maxm*2];
void add(int x,int y,int l)
{
e[cnt].to=y;
e[cnt].next=head[x];
e[cnt].l=l;
head[x]=cnt++;
}
void spfa(int s)
{
queue<int> q;
for(int i=0;i<=n;i++)
{
vis[s][i]=0;
dis[s][i]=inf;
}
dis[s][s]=0;
vis[s][s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
vis[s][u]=0;
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(dis[s][v]>dis[s][u]+e[i].l)
{
dis[s][v]=dis[s][u]+e[i].l;
if(!vis[s][v])
{
vis[s][v]=1;
q.push(v);
}
}
}
}
}
void solve()
{
int ans=-1,l1=0,l2=0;
for(int i=1;i<=n;i++)spfa(i);
for(int i=1;i<=n;i++)
{
l1=l2=0;
for(int j=1;j<=n;j++)
{
if(i==j)continue;
if(dis[i][j]>l1 && dis[i][j]!=inf)l2=l1,l1=dis[i][j];
else if(dis[i][j]>l2 && dis[i][j]!=inf)l2=dis[i][j];
}
if(l1 && l2)ans=max(ans,l1+l2);
}
cout<<ans<<endl;
}
int main()
{
int t,u,v,l;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
cnt=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&l);
add(u,v,l);
add(v,u,l);
}
solve();
}
return 0;
}