列表

详情


NC14550. 旅行

描述


小z放假了,准备到RRR城市旅行,其中这个城市有N个旅游景点。小z时间有限,只能在三个旅行景点进行游玩。小明租了辆车,司机很善良,说咱不计路程,只要你一次性缴费足够,我就带你走遍RRR城。

小z很开心,直接就把钱一次性缴足了。然而小z心机很重,他想选择的路程尽量长。

然而司机也很聪明,他每次从一个点走到另外一个点的时候都走最短路径。

你能帮帮小z吗?

需要保证这三个旅行景点一个作为起点,一个作为中转点一个作为终点。(一共三个景点,并且需要保证这三个景点不能重复).

输入描述

本题包含多组输入,第一行输入一个整数t,表示测试数据的组数
每组测试数据第一行输入两个数N,M表示RRR城一共有的旅游景点的数量,以及RRR城中有的路的数量。
接下来M行,每行三个数,a,b,c表示从a景点和b景点之间有一条长为c的路
t<=40
3<=N,M<=1000
1<=a,b<=N
1<=c<=100

输出描述

每组数据输出两行,
每组数据包含一行,输出一个数,表示整条路程的路长。
如果找不到可行解,输出-1.

示例1

输入:

4
7 7
1 2 100
2 3 100
1 4 4
4 5 6
5 6 10
1 6 4
6 7 8
7 3
1 2 1
1 3 1
1 3 2
7 3
1 2 1
3 4 1
5 6 1
8 9
1 2 1
2 3 1
3 4 1
4 1 1
4 5 1
5 6 1
6 7 1
7 8 1
8 5 1

输出:

422
3
-1
9

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 385ms, 内存消耗: 688K, 提交时间: 2020-08-23 13:01:03

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
vector<pii> e[1005];
int dis[1005],n,m;
queue<int> q;
int Dijkstra(int x)
{
    int i,len;
    memset(dis,0x3f3f3f,sizeof(dis));
    dis[x]=0;
    q.push(x);
    while(!q.empty())
    {
        int d=q.front();
        q.pop();
        len=e[d].size();
        for(i=0;i<len;i++)
            if(dis[e[d][i].first]>dis[d]+e[d][i].second)
            {
                dis[e[d][i].first]=dis[d]+e[d][i].second;
                q.push(e[d][i].first);
            }
    }
    sort(dis+1,dis+1+n);
    for(i=1;i<=n;i++)
        if(dis[i]>=0x3f3f3f)
            break;
    if(i>=4)
        return (dis[i-2]+dis[i-1]);
    else
        return -1;
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int from,to,c,i,sum=-1;
        cin>>n>>m;
        for(int i=1;i<=1000;i++)e[i].clear();
        for(i=1;i<=m;i++)
        {
            scanf("%d %d %d",&from,&to,&c);
            e[from].push_back(make_pair(to,c));
            e[to].push_back(make_pair(from,c));
        }
        for(i=1;i<=n;i++)
            sum=max(sum,Dijkstra(i));
        cout<<sum<<endl;
    }
}

C++(clang++ 11.0.1) 解法, 执行用时: 573ms, 内存消耗: 2220K, 提交时间: 2022-08-04 10:15:34

#include<bits/stdc++.h>
using namespace std;
const int N=120010;
int h[N],e[N],ne[N],w[N],idex,n,m,t,dist[N],res=-1;
bool st[N];
void add(int a,int b,int c){
	e[idex]=b;
	ne[idex]=h[a];
	w[idex]=c;
	h[a]=idex++;
}
void spfa(int s){
	memset(dist,0x3f,sizeof(dist));
	memset(st,false ,sizeof(st));
	queue<int>q;
	q.push(s);
	dist[s]=0;
	st[s]=true;
	while(!q.empty()){
		int pos=q.front();
		q.pop();
		st[pos]=false;
		for(int i=h[pos];i!=-1;i=ne[i]){
			if(dist[e[i]]>dist[pos]+w[i]){
				dist[e[i]]=dist[pos]+w[i];
				if(!st[e[i]]){
					st[e[i]]=true;
					q.push(e[i]);
				}
			}
		}
	}
	int cnt[N];
	cnt[0]=0;
	for(int i=1;i<=n;i++)if(dist[i]!=0x3f3f3f3f)cnt[++cnt[0]]=dist[i];
	if(cnt[0]>2){
		sort(cnt+1,cnt+cnt[0]+1);
		res=max(res,cnt[cnt[0]]+cnt[cnt[0]-1]);
	}
}
int main(){
	cin>>t;
	while(t--){
		res=-1;
		memset(h,-1,sizeof(h));
		memset(ne,-1,sizeof(ne));
		int a,b,c;
		scanf("%d%d",&n,&m);
		while(m--){
			scanf("%d%d%d",&a,&b,&c);
			add(a,b,c);
			add(b,a,c);
		}
		for(int i=1;i<=n;i++)spfa(i);
		printf("%d\n",res);
	}
}

上一题