当前位置: 首页 > news >正文

最短路基础模板题

P1339 [USACO09OCT] Heat Wave G

题目描述

有一个 n n n 个点 m m m 条边的无向图,请求出从 s s s t t t 的最短路长度。

输入格式

第一行四个正整数 n , m , s , t n,m,s,t n,m,s,t
接下来 m m m 行,每行三个正整数 u , v , w u,v,w u,v,w,表示一条连接 u , v u,v u,v,长为 w w w 的边。

输出格式

输出一行一个整数,表示答案。

输入输出样例 #1

输入 #1

7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

输出 #1

7

说明/提示

【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 2500 1\le n \le 2500 1n2500 1 ≤ m ≤ 6200 1\le m \le 6200 1m6200 1 ≤ w ≤ 1000 1\le w \le 1000 1w1000

【样例说明】
5 → 6 → 1 → 4 5 \to 6 \to 1 \to 4 5614 为最短路,长度为 3 + 1 + 3 = 7 3+1+3 = 7 3+1+3=7

数据量小,可以用各种方法,数据量大,邻接表优先,其次时间需要优化(最短路堆优化

堆优化的意义:O(n2)->O(mlog(n))

下面直接上代码

一维模拟邻接表(最难理解):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int w[N];
int e[N];
int h[N];
int ne[N];
int dis[N];
int is[N];
int n,m,qq,zz;
int q=0;
void jb(int a,int b,int c){
	w[q]=c;
	e[q]=b;
	ne[q]=h[a];
	h[a]=q++;
}
void dij(){
	memset(dis,0x3f,sizeof(dis));
	dis[qq]=0;
	for(int i=0;i<n;i++){
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!is[j]&&(t==-1||dis[j]<dis[t])){
				t=j;
			}
		}
		is[t]=1;
		for(int j=h[t];j!=-1;j=ne[j]){
			int k=w[j];
			dis[e[j]]=min(dis[e[j]],dis[t]+k);
		}
	}
}
int main() {
	memset(h,-1,sizeof(h));
	cin>>n>>m>>qq>>zz;
	for(int i=0;i<m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		jb(a,b,c);
		jb(b,a,c);
	}
	dij();
	cout<<dis[zz];
}`

邻接表+邻接矩阵(压力给到内存):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+10;
int g[N][N];
vector<int>s[N];
int dis[N];
int is[N];
int n,m,q,z;
void dij(){
	memset(dis,0x3f,sizeof(dis));
	dis[q]=0;
	for(int i=0;i<n;i++){
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!is[j]&&(t==-1||dis[j]<dis[t])){
				t=j;
			}
		}
		is[t]=1;
		for(int k=0;k<s[t].size();k++){
			dis[s[t][k]]=min(dis[s[t][k]],dis[t]+g[t][s[t][k]]);
		}
	}
}
int main() {
	//memset(g,0x3f,sizeof(g));
	
	cin>>n>>m>>q>>z;
	for(int i=0;i<m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		g[a][b]=c;
		g[b][a]=c;
		s[a].push_back(b);
		s[b].push_back(a);
	}
	dij();
	cout<<dis[z];
	return 0;
}

邻接表(容易理解):

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
struct f{
	int w;
	int e;
};
vector<f>s[N];
int dis[N];
int is[N];
int n,m,qq,zz;
void dij(){
	memset(dis,0x3f,sizeof(dis));
	dis[qq]=0;
	for(int i=0;i<n;i++){
		int t=-1;
		for(int j=1;j<=n;j++){
			if(!is[j]&&(t==-1||dis[j]<dis[t])){
				t=j;
			}
		}
		is[t]=1;
		for(int j=0;j<s[t].size();j++){
			f z=s[t][j];
			dis[z.e]=min(dis[z.e],dis[t]+z.w);
		}
	}
}
int main() {
	//memset(g,0x3f,sizeof(g));
	cin>>n>>m>>qq>>zz;
	for(int i=0;i<m;i++){
		int a,b,c;
		cin>>a>>b>>c;
		f z;
		z.e=b;
		z.w=c;
		s[a].push_back(z);
		z.e=a;
		s[b].push_back(z);
	}
	dij();
	cout<<dis[zz];
}

相关文章:

  • ctfshow VIP题目限免(前10题)
  • Kotlin语言进阶:协程、Flow、Channel详解(二)
  • 在K8S中,内置的污点主要有哪些?
  • 透视表(pivot table)中的某类型数据进行降序排列
  • HTML5
  • 《C++探幽:STL(string类源码的简易实现(上))》
  • 免费送源码:Java+ssm+MySQL 校园二手书销售平台设计与实现 计算机毕业设计原创定制
  • lower_bound 和 upper_bound 是两个强大的二分查找函数
  • Vue基础知识21-30
  • 55.跳跃游戏
  • 《比特城的七重结界:从数据洪流到量子盾牌的终极守护》
  • ZooKeeper集群部署(容器)
  • 如何深入理解C#中的备忘录模式(Memento Pattern)设计模式
  • Git常用问题收集
  • 创作五周年纪:数据之路的星光与远方
  • 深入理解 C++ 内置数组(四十三)
  • ​docker加docker compose实现软件快速安装启动
  • 唯美社区源码AM社区同款源码
  • 【MySQL | 八、 事务管理】
  • STM32F4系列ADC模块:原理、配置与实战应用
  • 从零开始学网站建设/常州seo第一人
  • 白银市城县建设局网站/用模板快速建站
  • 企业网站的作用/免费网站在线观看人数在哪直播
  • 网站可以换虚拟主机吗/网络营销技巧培训
  • 南宁公司网站设计/论坛软文案例
  • 视频网站建设报价单/网络营销活动策划方案模板