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度.这里就是如此.其他大家尽量理解.

相关推荐
你撅嘴真丑6 小时前
第九章-数字三角形
算法
在路上看风景6 小时前
19. 成员初始化列表和初始化对象
c++
uesowys6 小时前
Apache Spark算法开发指导-One-vs-Rest classifier
人工智能·算法·spark
zmzb01036 小时前
C++课后习题训练记录Day98
开发语言·c++
ValhallaCoder6 小时前
hot100-二叉树I
数据结构·python·算法·二叉树
董董灿是个攻城狮6 小时前
AI 视觉连载1:像素
算法
念风零壹6 小时前
C++ 内存避坑指南:如何用移动语义和智能指针解决“深拷贝”与“内存泄漏”
c++
智驱力人工智能7 小时前
小区高空抛物AI实时预警方案 筑牢社区头顶安全的实践 高空抛物检测 高空抛物监控安装教程 高空抛物误报率优化方案 高空抛物监控案例分享
人工智能·深度学习·opencv·算法·安全·yolo·边缘计算
孞㐑¥7 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
月挽清风7 小时前
代码随想录第十五天
数据结构·算法·leetcode