首页 > 编程语言 >【图论】3.30学习记录 k短路(A*算法)

【图论】3.30学习记录 k短路(A*算法)

时间:2024-03-30 22:33:06浏览次数:17  
标签:图论 const dij int 短路 pqq 算法 3.30

从最短路说起的k短路

3.26看了最短路和次短路。我们发现次短路实际上就是把最短路给破坏掉然后跑最短路...
那我想...是不是破坏(k-1)次就能得到k短路呢,很显然是的,但是复杂度比较高,(因为一次dij是 O(nlogn)级别的,次短路的话最坏要跑m次 当最短路有m条边的时候
那么k比较大的时候就只能选择更加便捷的算法了

A star算法

这个算法属于搜索的一种(虽然一说到搜索就想到DFS和BFS)
和DFS、BFS不同的是,另两个是把所有的可能性都遍历一遍,这个是选择当前情况下最好的往下遍历(也是能把所有的可能性都遍历了,但是是从最好的开始)

核心式子:F(x)=G(x)+H(x)

H(x)是从当前状态到最终状态的预计花费
G(x)是指从初始状态到当前状态n的实际花费
F(x)是从最初状态经过当前状态到最终状态的预计花费

何为当前情况下最好的:F(x)最小的
A star 算法的核心:求好H(x)函数

用A star 算法求解k短路

模板题:魔法猪学院
代入核心式子:

  1. H函数为当前状态到终点的预计最短路————通过反向跑dij进行预处理
  2. 模拟取F(x)最小的:优先队列模拟

code:

#include<bits/stdc++.h>
using namespace std;

// #define int long long
#define f first
#define s second

const int MAXN=5005;
const double inf=(1<<30);

double dist[MAXN];
int vis[MAXN];
int n,m;
double tt;

struct edge{
	int v;
	double dis;
	bool operator < (const edge &x)const{
		return dis>x.dis;
	}
};
struct statue{
	double f,g;
	int pos;
	friend bool operator < (const statue &x,const statue &y){
		return x.f>y.f;
	}
};

vector<pair<int,double> >e[MAXN],ee[MAXN];

priority_queue<edge>pq;
void dij(){
	for(int i=1;i<=n;i++){
		dist[i]=inf;
		vis[i]=0;
	}
	dist[n]=0;
	pq.push({n,dist[n]});
	while(!pq.empty()){
		auto j=pq.top();
		pq.pop();
		int u=j.v;
		if(vis[u])continue;
		vis[u]=1;
		for(auto i:ee[u]){
			int v=i.f;double w=i.s;
			if(dist[u]+w<dist[v]){
				dist[v]=dist[u]+w;
				if(!vis[v])pq.push({v,dist[v]});
			}
		}
	}
}
priority_queue<statue>pqq;
int ans=0;
void a_star(){
	statue p,m;
	p.pos=1,p.g=0,p.f=dist[1];
	pqq.push(p);
	while(!pqq.empty()){
		auto p=pqq.top();
		pqq.pop();
		int x=p.pos;
		if(x==n){
			if(tt>=p.f){
				ans++;
				tt-=p.f;
			}
			else return;
		}
		for(auto i:e[x]){
			int v=i.f;double w=i.s;
			m.pos=v,m.g=w+p.g;
			m.f=m.g+dist[v];
			pqq.push(m);
		}
	}
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n>>m>>tt;
	int u,v;double w;
	for(int i=1;i<=m;i++){
		cin>>u>>v>>w;
		e[u].push_back({v,w});
		ee[v].push_back({u,w});
	}
	dij();
	// for(int i=1;i<=n;i++){
	// 	cerr<<dist[i]<<" \n"[i==n];
	// }
	a_star();
	cout<<ans<<endl;
	// cerr<<tt<<endl;
}

标签:图论,const,dij,int,短路,pqq,算法,3.30
From: https://www.cnblogs.com/muyi-meow/p/18105861

相关文章

  • Tarjan 算法——图论学习笔记
    Part.1引入在图论问题中,我们经常去研究一些连通性问题,比如:有向图的联通性:传递闭包——Floyd算法;有向图连通性的对称性:强联通分量(SCC)——Tarjan算法缩点;无向图的联通性:并查集;无向图的关键边:桥(割边)、边双——Tarjan算法缩点;无向图的关键点:割点、点双——Tarjan建立圆方......
  • 2024.03.30 店小秘笔试
    1session是什么?cookie和session有什么联系?Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。2finalfinallyfinalize的区别?final。......
  • 2024.3.30 笔记
    AcWing372.棋盘覆盖设每个格子为\((i,j)\)\(i+j\)为偶数和\(i+j\)为奇数的点的两个集合构成二分图的两个点集,和为偶数的边的四周全是和为奇数的点,满足二分图的性质,题目即求以和为偶数和奇数的点构成的二分图的最大匹配constintdx[]={0,0,1,-1};constintdy[]=......
  • 搜索与图论(二)bfs---以题为例
    给定一个 n×m的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。最初,有一个人位于左上角 (1,1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。请问,该人从左上角移动至右下角 (n,m)处,至少需要移动多......
  • P8312 [COCI2021-2022#4] Autobus floyd最短路
    [P8312COCI2021-2022#4]Autobus-洛谷|计算机科学教育新生态(luogu.com.cn)思路:nnn数据范围很小可以用Floyd算法。注意:最多坐......
  • 安卓app 地铁最短路径查询 完成
     我通过三个函数完成了这个功能首先 创建哈希表根据起始站名终点站名然后根据哈希表建立起邻接表‘最后根据迪杰斯特拉算法完成这个功能/***function:起终查询*///构建邻接表publicstaticMap<String,Map<String,Integer>>buildAdja......
  • P1354 房间最短路问题
    原题链接题解1.最短路径一定可以表示成经过若干端点的线段,所以我们把端点单独提出来,这样就变成了计算几何形式的最短路2.如果两个端点能相连,代表他们之间没有墙阻挡code#include<bits/stdc++.h>usingnamespacestd;intn;struct{doublex,a1,b1,a2,b2;}wall[30];......
  • Floyd算法 【多源最短路】模板
    B3647【模板】Floyd-洛谷|计算机科学教育新生态(luogu.com.cn)#include<bits/stdc++.h>usingnamespacestd;constintN=1e2+10;constintinf=0x3f3f3f;intn,m;intg[N][N];voidfloyd(){for(intk=1;k<=n;k++){for(inti=1;i<=n;i++)......
  • 【图论】3.26学习记录 最短路/最长路 次短路
    最短路:SPFA:特点:代码短好写,负权边必备,可以判环,容易被卡成O(nm);code:#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintMAXN=5e5+10;constintinf=2147483647;intdist[MAXN];intvis[MAXN];vector<pair<int,int>>e[MAXN];si......
  • 【图论 | 数据结构】用链式前向星存图(保姆级教程,详细图解+完整代码)
    一、概述链式前向星是一种用于存储图的数据结构,特别适合于存储稀疏图,它可以有效地存储图的边和节点信息,以及边的权重。它的主要思想是将每个节点的所有出边存储在一起,通过数组的方式连接(类似静态数组实现链表)。这种方法的优点是存储空间小,查询速度快,尤其适合于处理大规模......