旅行

思路:

每次选一个点作为中间点,然后跑一边单源最短路,记录距离最远的两个点的距离和,答案就是最大的和,注意多组测试数据的初始化,直接套模板

#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;
}