A* k短路 学习笔记

题目大意

n个点,m条边有向图,给定S,T,求不严格k短路
n<=1000 m<=100000 k<=1000
不用LL

分析

A*算法
f(i)表示从S出发经过i到T的估价函数
\(f(i)=g(i)+h(i)\)
g(i)表示S-i的实际代价
h(i)表示i-T的估计代价
要保证h(n)小于等于n到t的实际代价
本题中h(i)估价用逆图dijkstra一波直接求i-T最短路径作为估价
然后从S开始按照f为关键字用堆优化搜索
其实写法是类似于dijkstra的
不难从f(i)如果出现了K+1短,K+1短及之后都可以不要的
所以记录cnt[i]
每个点i出队一次,就找到了第++cnt[i]个f(i)
当T第k次出队就是答案

注意

dijkstra和Astar是可以共用一个结构体进行堆优化的

solution

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <queue>
using namespace std;
const int N=1007;
const int M=100007;

inline int rd(){
	int x=0;bool f=1;char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
	for(;isdigit(c);c=getchar()) x=x*10+c-48;
	return f?x:-x;
}

int n,m;
int S,K,T;
int g[N],te;
int hd[N],tb;
struct edge{
	int y,d,next;
}e[M<<1],bck[M<<1];

void addedge(int x,int y,int z){
	e[++te].y=y;e[te].d=z;e[te].next=g[x];g[x]=te;
}

void addbck(int x,int y,int z){
	bck[++tb].y=y;bck[tb].d=z;bck[tb].next=hd[x];hd[x]=tb;
}

struct node{
	int id,g,f;
	node(int ii=0,int gg=0,int ff=0){id=ii;g=gg;f=ff;}
	bool operator < (node b) const{
		return f>b.f;
	}
};

priority_queue<node>q;

int h[N],vis[N];

void dijkstra(){
	q.push(node(T,0,0));
	memset(h,127,sizeof(h));
	h[T]=0;
	
	int x,p,y;
	node nw;
	while(!q.empty()){
		nw=q.top();q.pop();
		x=nw.id;
		if(vis[x]) continue;
		vis[x]=1;
		for(p=hd[x];p;p=bck[p].next){
			y=bck[p].y;
			if(h[x]+bck[p].d<h[y]){
				h[y]=h[x]+bck[p].d;
				q.push(node(y,0,h[y]));
			}
		}
	}
}

int cnt[N];

bool Astar(){
	q.push(node(S,0,h[S]));
	int x,p,y;
	node nw;
	while(!q.empty()){
		nw=q.top();q.pop();
		x=nw.id;
		cnt[x]++;
		if(cnt[x]==K&&x==T){
			printf("%d\n",nw.f);
			return 1;
		}
		if(cnt[x]>K) continue;
		for(p=g[x];p;p=e[p].next){
			y=e[p].y;
			q.push(node(y,nw.g+e[p].d,nw.g+e[p].d+h[y]));
		}
	}
	return 0;
}

int main(){
	int i,x,y,z;
	n=rd(),m=rd();
	for(i=1;i<=m;i++){
		x=rd(),y=rd(),z=rd();
		addedge(x,y,z);
		addbck(y,x,z);
	}
	S=rd(),T=rd(),K=rd();
	dijkstra();
	if(Astar()==0) puts("-1");
	return 0;
}
posted @ 2017-02-14 19:22  _zwl  阅读(250)  评论(0编辑  收藏  举报