P2865 [USACO06NOV] Roadblocks G 题解

题意

这题给你一个无向图,让你求出次短路(比最短路长,比其他路短).

思维

这里要注意到题目是人类出的,也是给人类做的,更何况这只是一道蓝题,所以极大概率不是让你发明新算法.因此这里最有可能是最短路的变形题.我们发现次短路与最短路是有关系的,因为构成一个次短路只有两种可能:

1.固定一条边,求出起点和终点分别到端点的最短路径,这种路径可能是次短路.注意判定是否你直接找到最短路了.

2.最短路的一条边被重复走了.为什么不是多条边被重复走?因为这样就比只重复一条边的长了,不是次短路.

两种枚举即可.

算法

这里求最短路dijikstra SPFA都可以,作者用的是堆优化的dijikstra,因为某个算法已经死了,如果这是考场且没有负权边一定用dijikstra.

实现

dis数组开两个(或者开一个二维的),分别存从起点和终点跑的最短路,这样思路中的两种枚举方式都可以简单实现.要注意,第一种方法中枚举不要出现走重的情况,因为这种情况绝对不是次短路.

cpp 复制代码
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=5e3+10, M=1e5+10;
ll n,m,dis[N][2],mi,ans=(1e12),sl=(1e12);
bool f[N];
struct node{
	ll u,d;
	bool operator < (const node &u) const{
		return u.d<d;
	}
};
vector<node>v[N];
void dij(int s, int x){
	priority_queue<node>q;
	for(int i=1;i<=n;i++) dis[i][x]=(1e12), f[i]=0;
	dis[s][x]=0, q.push({s,0});
	while(q.size()){
		node t=q.top();
		q.pop();
		if(f[t.u]) continue;
		else f[t.u]=1;
		for(int i=0;i<v[t.u].size();i++){
			int u=v[t.u][i].u, g=v[t.u][i].d;
			if(dis[u][x]>dis[t.u][x]+g){
				dis[u][x]=dis[t.u][x]+g, q.push({u,dis[u][x]});
			}
		}
	}
}
struct Edge{
	int u,v,w;
}t[M];
int main(){
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		cin>>t[i].u>>t[i].v>>t[i].w;
		v[t[i].u].pb({t[i].v,t[i].w});
		v[t[i].v].pb({t[i].u,t[i].w});
	}
	dij(1,0), dij(n,1), mi=dis[n][0];
	for(int i=1;i<=m;i++){
		ll u=t[i].u, v=t[i].v, w=t[i].w;
		if(dis[u][0]+dis[v][1]>dis[u][1]+dis[v][0]) swap(u,v);
		ll s=dis[u][0]+dis[v][1]+w;
		if(s==mi) continue;
		ans=min(ans,s);
	}
	for(int i=1;i<=m;i++){
		ll u=t[i].u, v=t[i].v, w=t[i].w;
		if(dis[u][0]+dis[v][1]>dis[u][1]+dis[v][0]) swap(u,v);
		ll s=dis[u][0]+dis[v][1]+w;
		if(s!=mi) continue;
		sl=min(sl,w);		
	}ans=min(ans,mi+sl*2);
	cout<<ans;
	return 0;
}

这里两个swap可能匪夷所思,想象一根木棒两端固定在两个端点(起点和终点),很显然有两种摆法,一种摆法非常奇怪,绳子会长很多,因为这个摆法是从一条直线转了180度.这里就是如此.其他大家尽量理解.

相关推荐
MediaTea1 小时前
Python 库手册:gc 垃圾回收
java·开发语言·jvm·python·算法
ZhiqianXia1 小时前
图论中常见不变量与性质全集(带严格数学公式)
图论
Chrikk1 小时前
【上篇】AI 基础设施中的现代C++:显存安全 零拷贝
c++·c++40周年
QxQ么么7 小时前
移远通信(桂林)26校招-助理AI算法工程师-面试纪录
人工智能·python·算法·面试
止观止9 小时前
C++20 Concepts:让模板错误信息不再“天书”
c++·c++20·编程技巧·模板编程·concepts
FL16238631299 小时前
ONNX RuntimeC++ 静态库下载安装和使用教程
开发语言·c++
Mz12219 小时前
day05 移动零、盛水最多的容器、三数之和
数据结构·算法·leetcode
SoleMotive.9 小时前
如果用户反映页面跳转得非常慢,该如何排查
jvm·数据库·redis·算法·缓存