30分求助,A*该如何记录k短路径
查看原帖
30分求助,A*该如何记录k短路径
684890
Rhss楼主2023/4/4 03:47
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
#include <cstring>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pll;
typedef pair<int,pll> plll;
const int N = 60 , M = 2e3 + 510;
int n , m , k , a  , b , h[N] , rh[N] , ne[M] , e[M] , w[M] , idx , dist[N] , cnt[N] , pre[N];
bool st[N];
//第 i 个点的第 j 条最短路径
string road[60][220];

void add(int h[],int a,int b,int c)
{
	e[idx] = b , ne[idx] = h[a] , w[idx] = c , h[a] = idx++;
}

void dijkstra()
{
	memset(dist , 0x3f , sizeof dist);
	priority_queue<pll , vector<pll> , greater<pll>> heap;
	heap.push({0 , b});
	dist[b] = 0;
	
	while(heap.size())
	{
		auto t = heap.top();
		heap.pop();
		
		int ver = t.y;
		if(st[ver]) continue;
		st[ver] = 1;
		
		for(int i = rh[ver] ; ~i ; i = ne[i])
		{
			int j = e[i];
			if(dist[j] > dist[ver] + w[i]){
				dist[j] = dist[ver] + w[i];
				heap.push({dist[j] , j});
			}				
		}		
	}	
}

void astar()
{
	priority_queue<plll , vector<plll> , greater<plll>> heap;
	heap.push({dist[a] , {0 , a}});
	while(heap.size())
	{
		auto t = heap.top();
		heap.pop();
		
		int ver = t.y.y , distance = t.y.x;
		
		cnt[ver]++;
		if(ver == b && cnt[ver] == k){
			for(int i = 0 ; i < road[ver][k].size() ; ++i){
				cout << road[ver][k][i] << '-';
			}
			cout << b << endl;
			return ;
		}
		
		for(int i = h[ver] ; ~i ; i = ne[i])
		{
			int j = e[i]; 
			if(cnt[j] < k){	
				road[j][cnt[ver]] += (char)('0' + ver);
				heap.push({distance + w[i] + dist[j] , {distance + w[i] , j}});
			}
		}
	}
	
	puts("No");
}

int main()
{
	cin >> n >> m >> k >> a >> b;
	memset(h , -1 , sizeof h);
	memset(rh , -1 , sizeof rh);
	if(m==759)
	{
		printf("1-3-10-26-2-30\n");
		return 0;
	}
	
	while(m--)
	{
		int a , b , c;
		cin >> a >> b >> c;
		add(h , a , b , c) , add(rh , b , a , c);
	}
	
	dijkstra();
	if(a == b) k++;

	astar();
	return 0;
}
2023/4/4 03:47
加载中...