链接:https://ac.nowcoder.com/acm/problem/14352 来源:牛客网

题目描述 小z放假了,准备到RRR城市旅行,其中这个城市有N个旅游景点。小z时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍RRR城。 小z很开心,直接就把钱一次性缴足了。然而小z心机很重,他想选择的路程尽量长。 然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。 你能帮帮小z吗? 需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复).

采用的算法为堆优化的dijkstra算法,分别遍历每一个中转点,找到用算法处理后距离该中转点距离最远的两个点作为起点和终点。

注意事项:1,数组的大小问题2,题目描述为稀疏图,故采取邻接表来储存图(注意邻接表的数组大小)。 经验分享: 1,邻接表中e[],ne[]的大小应该是边的个数,定为点的个数的二倍较好。2,初始化边的长度为正无穷,可采用memset(dis,0x3f,sizeof(dis)),最好保证设定的正无穷的值大于最大边长度的二倍。


#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 1010;

typedef pair<int, int> PII;

int h[N],e[2*N],ne[2*N],w[2*N],dis[N];
//虽然题目描述为M<=1000,但是如果数组设定为N大小的话,会越界导致超时
int n,m,t,idx;
bool st[N];

void add(int a,int b,int c)//插入操作
{
    e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}

int dijkstra(int i)//采用堆优化的·dijkstra算法
{
    int max1=0,max2=0;//用max1,max2存储最长的两条路径
    memset(dis,0x3f,sizeof(dis));
    dis[i]=0;
    
    priority_queue<PII,vector<PII>,greater<PII>> heap;//设定为小根堆
    heap.push({0,i});
    
    while(heap.size())
    {
        auto t=heap.top();
        heap.pop();
        
        int distance=t.first,ver=t.second;
        if(st[ver])continue;
        st[ver]=true;
        max2=max(max2,dis[ver]);
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dis[j]>distance+w[i])
            {
                dis[j]=distance+w[i];
                heap.push({dis[j],j});
            }
        }
        if(max2>max1)swap(max1,max2);
    }
    for(int i=1;i<=n;i++) st[i]=false;
    if(max2==0)return -1;
    else return max1+max2;
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        memset(h,-1,sizeof(h));
        scanf("%d%d",&n,&m);
        while(m--)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c),add(b,a,c);//题目描述不明白,城市之间应该是无向图,故插入两次
        }
        int x=-1;
        for(int i=1;i<=n;i++)
        {
            x=max(dijkstra(i),x);
        }
        printf("%d\n",x);
        idx=0;
    }
    return 0;
}