POJ2449 Remmarguts' Date k短路 A*

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36797646/article/details/83864350

题解:

k k 短路裸题,今天看了一下,顺便学习了一发 A A *的思想。
如果直接暴力做的话,那么就是当 T T k k 次出堆的时候就是答案,但是这样的话 k k 短路上的所有点都要出堆 k k 次,复杂度不能承受。考虑优化,如果一个点的当前距离很短,但是它到终点的距离很长,那么它是不优秀的,所以可以加上一个估价函数,预估他到终点的距离,每次选择当前距离+预估距离最小的元素出堆,这样一来每个点的出堆次数不会太多,即可通过。
值得一提的是估价函数的设置,一开始我用的是当前距离+当前点到终点最短路,我认为这样更加接近实际答案,但是这样MLE了,入堆节点太多,直接用当前点到终点最短路就能AC了。

代码:

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=1010;
const int Maxm=100010;
const int inf=2147483647;
int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
int n,m,S,T,k;
struct Edge{int y,d,next;}e[Maxm];
int last[Maxn],len;
void ins(int x,int y,int d)
{
	int t=++len;
	e[t].y=y;e[t].d=d;e[t].next=last[x];last[x]=t;
}
struct Node
{
	int x,t1,t2;
	Node(int _x,int _t1,int _t2){x=_x,t1=_t1,t2=_t2;}
};
bool operator < (Node a,Node b){return a.t1+a.t2>b.t1+b.t2;}
int cnt[Maxn],f[Maxn];
void dijkstra()
{
	memset(f,63,sizeof(f));f[T]=0;
	memset(cnt,0,sizeof(cnt));
	priority_queue<Node>q;q.push(Node(T,0,0));
	while(!q.empty())
	{
		Node tmp=q.top();q.pop();
		int x=tmp.x;
		if(cnt[x])continue;
		cnt[x]++;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].y;
			if(f[x]+e[i].d<f[y])
			{
				f[y]=f[x]+e[i].d;
				q.push(Node(y,f[y],0));
			}
		}
	}
}
void kth()
{
	memset(cnt,0,sizeof(cnt));
	priority_queue<Node>q;q.push(Node(S,0,f[S]));
	while(!q.empty())
	{
		Node tmp=q.top();q.pop();
		int x=tmp.x;
		cnt[x]++;
		if(x==T&&cnt[T]==k){printf("%d",tmp.t1);return;}
		if(cnt[x]>k)continue;
		for(int i=last[x];i;i=e[i].next)
		{
			int y=e[i].y;
			q.push(Node(y,tmp.t1+e[i].d,f[y]));
		}
	}
	puts("-1");
}
int X[Maxm],Y[Maxm],D[Maxm];
int main()
{
	n=read(),m=read();
	for(int i=1;i<=m;i++)
	{
		X[i]=read(),Y[i]=read(),D[i]=read();
		ins(Y[i],X[i],D[i]);
	}
	S=read(),T=read(),k=read();
	if(S==T)k++;
	dijkstra();
	memset(last,0,sizeof(last));len=0;
	for(int i=1;i<=m;i++)ins(X[i],Y[i],D[i]);
	kth();
}

猜你喜欢

转载自blog.csdn.net/baidu_36797646/article/details/83864350