pku2449第K短路 最短路+A*

        题意:求一点至另一点的第K短路。注意如果起点和终点一样的话,那么刚开始起点不算到达终点。

        分析:寻找最短路,直接SPFA就可以了。。。这里是第K短路,把每一条路径都找出来。开始想用DP,dp[i][j]表示到i结点第j大的路径权值是多少,但这样还是搜,而且会超时。。。所以还不如用A*搜,用优先队列每次将按照所走路径权值的最小值+此点到终点的最短距离的最小值出队列。

        注意计算第几次到达某个点时是以出队列的时候算的,而不是入队列。开始求每个点到终点的最短路,建反向图,再用SPFA。。。

#include<stdio.h>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;

const int maxn=1100;
const int maxm=110000;
const int INF=0x3fffffff;
struct edge
{
	int u,v,w;
}p0,p1;

vector<edge>e[maxn],e1[maxn];

int dist[maxn],times[maxn],n,m,S,T,K;

bool operator >(edge a,edge b)
{
	return a.w+dist[a.v]>b.w+dist[b.v];
}
priority_queue<edge,vector<edge>,greater<edge> >p;

void SPFA(int s)
{
	int i,j,k,head=0,tail=0,q[maxn*2];
	bool inq[maxn];
	for(i=1;i<=n;i++)
		dist[i]=INF,inq[i]=false;
	dist[s]=0,inq[s]=true;
	q[tail++]=s;
	while(head!=tail)
	{
		k=q[head];
		inq[k]=false;
		head=(head+1)%(2*maxn);
		for(i=0;i<e1[k].size();i++)
		{
			j=e1[k][i].v;
			if(dist[j]>dist[k]+e1[k][i].w)
			{
				dist[j]=dist[k]+e1[k][i].w;
				if(!inq[j])
				{
					inq[j]=true;
					q[tail]=j;
					tail=(tail+1)%(2*maxn);
				}
			}
		}
	}
}
void Search()
{
	int i,now;
	bool tag=false;
	while(!p.empty()) p.pop();
	memset(times,0,sizeof(times));
	p0.v=S,p0.w=0;
	p.push(p0);
	while(!p.empty())
	{
		p0=p.top();
		p.pop();
		if(++times[p0.v]>=K)
		{
			if(p0.v==T)
			{
				if(S!=T||(S==T&×[p0.v]==K+1))//如果起点和终点一样,那么一定要走才算一条路径
				{
					tag=true;
					printf("%d\n",p0.w);
					break;
				}
			}
			if(times[p0.v]>K)
				continue;
		}
		now=p0.v;
		for(i=0;i<e[now].size();i++)
		{
			p1.v=e[now][i].v;
			p1.w=e[now][i].w+p0.w;
			p.push(p1);
		}
	}
	if(!tag) printf("-1\n");
}
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(i=1;i<=n;i++)
		{
			e1[i].clear();
			e[i].clear();
		}
		for(i=0;i<m;i++)
		{
			scanf("%d%d%d",&p0.u,&p0.v,&p0.w);
			e[p0.u].push_back(p0);
			j=p0.u;
			p0.u=p0.v;
			p0.v=j;
			e1[p0.u].push_back(p0);
		}
		scanf("%d%d%d",&S,&T,&K);
		SPFA(T);
		if(dist[S]==INF)
		{
			printf("-1\n");
			continue;
		}
		Search();
	}
	return 0;
}


 

你可能感兴趣的:(pku2449第K短路 最短路+A*)