旅行
思路:
每次选一个点作为中间点,然后跑一边单源最短路,记录距离最远的两个点的距离和,答案就是最大的和,注意多组测试数据的初始化,直接套模板
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 1010, M = N * 2, INF = 0x3f3f3f3f;
typedef pair<int, int> PII;
typedef long long LL;
int h[M], w[M], e[M], ne[M], idx;
int n, m;
int d[N];
bool st[N];
void init()
{
memset(h, -1, sizeof h); idx = 0;
}
void add(int a, int b, int c)
{
w[idx] = c, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int dijkstra(int s)
{
int d1 = 0, d2 = 0;//最远的两个点
memset(d, 0x3f, sizeof d);
memset(st, 0, sizeof st);
d[s] = 0;
priority_queue<PII, vector<PII>, greater<PII>> heap;
heap.push({0, s});
while(!heap.empty())
{
auto t = heap.top();
heap.pop();
int ver = t.second, dist = t.first;
if(st[ver]) continue;
st[ver] = true;
d2 = max(d2, d[ver]);//更新最短的两个点
if(d2 > d1) swap(d2, d1);
for(int i = h[ver]; ~i; i = ne[i])
{
int j = e[i];
if(d[j] > dist + w[i])
{
d[j] = dist + w[i];
heap.push({d[j], j});
}
}
}
if(!d2) return 0;//如果d2 = 0说明找不到符合条件的两个点,大概率是图不连通
return (d1 + d2);
}
int main()
{
int t;
cin >> t;
while(t --)
{
cin >> n >> m;
init();
while(m --)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c), add(b, a, c);
}
int ans = 0;
for(int i = 1; i <= n; i ++) ans = max(dijkstra(i), ans);
if(ans == 0) ans = -1;
printf("%d\n", ans);
}
return 0;
}