poj 2449 Remmarguts' Date(A*+spfa)

Remmarguts' Date

Time Limit: 4000MS   Memory Limit: 65536K
Total Submissions: 37028   Accepted: 10206

Description

"Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, he told them a story. 

"Prince Remmarguts lives in his kingdom UDF – United Delta of Freedom. One day their neighboring country sent them Princess Uyuw on a diplomatic mission." 

"Erenow, the princess sent Remmarguts a letter, informing him that she would come to the hall and hold commercial talks with UDF if and only if the prince go and meet her via the K-th shortest path. (in fact, Uyuw does not want to come at all)" 

Being interested in the trade development and such a lovely girl, Prince Remmarguts really became enamored. He needs you - the prime minister's help! 

DETAILS: UDF's capital consists of N stations. The hall is numbered S, while the station numbered T denotes prince' current place. M muddy directed sideways connect some of the stations. Remmarguts' path to welcome the princess might include the same station twice or more than twice, even it is the station with number S or T. Different paths with same length will be considered disparate. 

Input

The first line contains two integer numbers N and M (1 <= N <= 1000, 0 <= M <= 100000). Stations are numbered from 1 to N. Each of the following M lines contains three integer numbers A, B and T (1 <= A, B <= N, 1 <= T <= 100). It shows that there is a directed sideway from A-th station to B-th station with time T. 

The last line consists of three integer numbers S, T and K (1 <= S, T <= N, 1 <= K <= 1000).

Output

A single line consisting of a single integer number: the length (time required) to welcome Princess Uyuw using the K-th shortest path. If K-th shortest path does not exist, you should output "-1" (without quotes) instead.

Sample Input

2 2
1 2 5
2 1 4
1 2 2

Sample Output

14

Source

POJ Monthly,Zeyuan Zhu

题意:求第K短路,每个点可以重复访问。

思路:A*算法的应用。A*是一种求解最短路的算法。

设源点为s,目标点为t,当前点为x;

g(x):表示从s到达x的实际距离;

h(x):表示从x到达t的估计距离;

f(x)=g(x)+h(x);

表示按照到达x点的走法从s到达t的估计距离(实际距离+估计距离=估计距离)。

因此我们需要先求得每一个点x到目标点t的距离即h(x);建立反向边,使用任意的最短路径算法即可求的h(x)


A*算法的本质是BFS,使用优先队列目的是每次取的f(x)为最小。因此每次出队的点如果是t。则对应的f(x)的就为最短距离。出队k次,则对应的f(x)为k短路。

AC代码:

A*(图的搜索方法)+spfa(计算h(x))+链式前向星(存边)

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 1e3+5;
const int MAXM = 5e5+5;
const int INF = 0x3f3f3f3f;

struct A{
	int f,g,v;
	//从小到大排序
	bool operator <(const A a)const{
		if(a.f==f) return a.g<g;
		return a.f<f;
	}
};
priority_queue<A> q2;
struct Edge{
	int next,v,w;
}edge[MAXM],revedge[MAXM];
int cnt,vis[MAXN],d[MAXN],head[MAXM],revhead[MAXM];
queue<int> q1;

void add(int u,int v,int w){
	edge[cnt]=(Edge){head[u],v,w};
	head[u]=cnt++;
	revedge[cnt]=(Edge){revhead[v],u,w};
	revhead[v]=cnt++;
}

void spfa(int s){
	fill(d,d+MAXN,INF);
	memset(vis,0,sizeof(vis));
	d[s]=0;
	q1.push(s);
	while(!q1.empty()){
		int u = q1.front();
		q1.pop();
		vis[u]=false;
		for(int i=revhead[u];~i;i=revedge[i].next){
			int v=revedge[i].v;
			int w=revedge[i].w;
			if(d[v]>d[u]+w){
				d[v]=d[u]+w;
				if(!vis[v]){
					vis[v]=true;
					q1.push(v);
				}
			}
		}
	}
}

int Astar(int s,int t,int k){
	int tmp=0;//记录终点第几次出队
	while(!q2.empty()){
		q2.pop();
	}
	/*如果起点与终点为同一点
	,不移动不算为一条路径,
	然而我们却多统计了这一条,故k++;*/
	if(s==t) k++;
	//图不是连通图
	if(d[s]==INF) return -1;
	A x;
	x.v=s;x.g=0;x.f=x.g+d[s];
	q2.push(x);
	while(!q2.empty()){
		A now = q2.top();
		q2.pop();
		if(now.v==t){
			tmp++;
			if(tmp==k) return now.g;
		}
		for(int i=head[now.v];~i;i=edge[i].next){
			x.v=edge[i].v;
			x.g=now.g+edge[i].w;
			x.f=x.g+d[x.v];
			q2.push(x);
		}
	}
	return -1;
}

int main(){
	int n,m;
	while(~scanf("%d%d",&n,&m)){
		memset(head,-1,sizeof(head));
		memset(revhead,-1,sizeof(revhead));
		cnt=0;
		for(int i=0;i<m;i++){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			add(u,v,w);
		}
		int s,t,k;
		scanf("%d%d%d",&s,&t,&k);
		spfa(t);
		printf("%d\n",Astar(s,t,k));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Rainbow_storm/article/details/82562437