POJ 2449 Remmarguts' Date(A*K短路) xgtao

Remmarguts' Date

给出原点和终点,给出一个有向图,问起点到终点的第k短的路有多长。

首先确定这是一道搜索的题目,然而Gemini说这是一道A*,既然是A*那么就有估计值和实际值,估计值不好在搜索的时候计算,那么就先把距离预处理出来,就从终点到起点Dijsktra,最后再从起点A*,当终点进入优先队列k次时,那么所走的路径一定是第k短路。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;

const int inf = (1<<31)-1;
const int maxn = 1010;
const int maxm = 100010;
#define clr(a,b) memset(a,b,sizeof(a))
int n,m;
int u,v,w,s,t,k;
int dis[maxn],done[maxn],cnt[maxn];
struct Edge{
	int u,v,w;
	Edge *nxt;
}meo[2*maxm],*head[maxn],*cur,*rehead[maxn];
struct node{
	int dis,u;
	bool operator < (const node &rhs)const{
		return dis>rhs.dis;
	}
};
struct star{
	int d,u;
	bool operator < (const star &rhs)const{
		return d+dis[u]>rhs.d+dis[rhs.u];//*****
	}
};
void adde(int u,int v,int w,Edge *f[]){
	cur->v = v;
	cur->w = w;
	cur->nxt = f[u];
	f[u] = cur++;
//	printf("!%d %d %d\n",u,v,w);
}

void dijkstra(int s){
	priority_queue<node>q;
	for(int i = 1;i <= n;++i)dis[i] = inf;
	dis[s] = 0;
	q.push((node){dis[s],s});
	while(!q.empty()){
		node p = q.top();
		q.pop();
		int u = p.u;
		if(done[u])continue;
		done[u] = true;
		for(Edge *it = rehead[u];it;it = it->nxt){
			int v = it->v;
			if(dis[v] > dis[u]+it->w){
				dis[v] = dis[u] + it->w;
				q.push((node){dis[v],v});
			}
		}
	}
//	for(int i = 1;i <= n;++i)printf("%d ",dis[i]);puts("");
}

int AStar(int s,int t){
	if(dis[s] == inf)return -1;
	if(s == t)++k;//*****
	priority_queue <star> q;
	q.push((star){0,s});
	while(!q.empty()){
		star p = q.top();
		q.pop();
		cnt[p.u]++;
		if(cnt[t] == k)return p.d;
		for(Edge *it = head[p.u];it;it = it->nxt){
			q.push((star){it->w+p.d,it->v});
		}
	}
	return -1;
}

int main(){
	cur = meo;
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= m;++i){
		scanf("%d%d%d",&u,&v,&w);
		adde(u,v,w,head);
		adde(v,u,w,rehead);
	}
	scanf("%d%d%d",&s,&t,&k);
	dijkstra(t);
	printf("%d\n",AStar(s,t));
	return 0;
}

  

原文地址:https://www.cnblogs.com/xgtao984/p/5690494.html