[POJ2449] Remmarguts' Date

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

题意

(n)个点(m)条边的有向图,求图中两点间第(K)短路。

  • 输入第一行为顶点数(N),边数(M)

  • 接下来(2)(M+1)行,每行(3)个数:(u)(v)(w),表示(u)(v)有一条边权为(w)的有向边;

  • 最后一行(3)个整数:(From)(To)(Cnt),表示题目要求求(From)(To)的第(Cnt)小的路径。

  • (PS):如果没有(From)(To)的第(Cnt)小的路径,则输出(-1)

题解

(K)短路的模板题,这里着重讲解一下思路:

首先我们需要用两个边集数组,一个用来记录输入的边的信息,另一个记录反向边。

再以终点为源点跑一趟(Dijkstra),注意边要用反向边。

接下来才是重点:(A*)求第(K)短路,我们先解释定义

struct node
{
	int id,f,g;
	bool operator<(node tmp) const
	{
		if(f==tmp.f) return g>tmp.g;
		return f>tmp.f;
	}
};
priority_queue<node> q;
  • (id)记录当前的点的编号

  • (f)为一个估计:按照当前到达(id)(+)(id)到达(To)的最段路,即按照当前的遍历了的总边权与后面估计距离的最小值

  • (g)为已经遍历了的总边权

再看看(A*)算法的核心:

void A_star()
{
	if(From==To) ++Cnt;
	q.push((node){From,0,0});
	node nw; int to;
	while(!q.empty())
	{
		nw=q.top(); q.pop();
		if(nw.id==To)
			if(!(--Cnt)) {printf("%d
",nw.g);return;}
		for(int i=hd1[nw.id];i;i=e1[i].nt)
		{
			to=e1[i].to;
			q.push((node){to,nw.g+e1[i].ds+dis[to],nw.g+e1[i].ds});
		}
	}
	puts("-1");
}
  • 首先的这个是个坑点:if(From==To) ++Cnt;,即起点等于终点的情况

  • 接下来的(BFS)难度不大,此处不予以解释

上代码:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#include<bitset>
using namespace std;

const int N=5001,NE=200001;
struct edge
{
	int to,ds,nt;
}e1[NE],e2[NE];
int n,m,ne1,ne2,hd1[N],hd2[N],dis[N],From,To,Cnt;

void Read()
{
	int u,v,w;
	for(scanf("%d%d",&n,&m);m;--m)
	{
		scanf("%d%d%d",&u,&v,&w);
		++ne1,e1[ne1]=(edge){v,w,hd1[u]},hd1[u]=ne1,
		++ne2,e2[ne2]=(edge){u,w,hd2[v]},hd2[v]=ne2;
	}
	scanf("%d%d%d",&From,&To,&Cnt);
}

typedef pair<int,int> pr;
priority_queue<pr,vector<pr>,greater<pr> > Q;
bool vis[N];
const int INF=99999999;
void Dijkstra(int s)
{
	for(int i=1;i<=n;++i) dis[i]=INF;
	dis[s]=0;
	Q.push(make_pair(dis[s],s));
	int nw,nt;
	while(!Q.empty())
	{
		nw=Q.top().second; Q.pop();
		if(vis[nw]) continue;
		vis[nw]=1;
		for(int i=hd2[nw];i;i=e2[i].nt)
		{
			nt=e2[i].to;
			if(dis[nt]>dis[nw]+e2[i].ds)
			{
				dis[nt]=dis[nw]+e2[i].ds;
				Q.push(make_pair(dis[nt],nt));
			}
		}
	}
}

struct node
{
	int id,f,g;
	bool operator<(node tmp) const
	{
		if(f==tmp.f) return g>tmp.g;
		return f>tmp.f;
	}
};
priority_queue<node> q;

void A_star()
{
	if(From==To) ++Cnt;
	q.push((node){From,0,0});
	node nw; int to;
	while(!q.empty())
	{
		nw=q.top(); q.pop();
		if(nw.id==To)
			if(!(--Cnt)) {printf("%d
",nw.g);return;}
		for(int i=hd1[nw.id];i;i=e1[i].nt)
		{
			to=e1[i].to;
			q.push((node){to,nw.g+e1[i].ds+dis[to],nw.g+e1[i].ds});
		}
	}
	puts("-1");
}

int main()
{
	Read(),
	Dijkstra(To),
	A_star();
	return 0;
}

本文作者:OItby @ https://www.cnblogs.com/hihocoder/

未经允许,请勿转载。

原文地址:https://www.cnblogs.com/hihocoder/p/11479293.html