zoukankan      html  css  js  c++  java
  • [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/

    未经允许,请勿转载。

  • 相关阅读:
    【搜索引擎Jediael开发笔记1】搜索引擎初步介绍及网络爬虫 2014-05-23 14:07 515人阅读 评论(0) 收藏
    【搜索引擎基础知识3】搜索引擎相关开源项目及网站 2014-05-23 11:44 757人阅读 评论(0) 收藏
    HtmlParser基础教程 分类: C_OHTERS 2014-05-22 11:33 1649人阅读 评论(1) 收藏
    【搜索引擎Jediael开发4】V0.01完整代码 分类: H_HISTORY 2014-05-21 21:35 470人阅读 评论(0) 收藏
    学习金字塔 分类: T_TALENT 2014-05-21 09:25 331人阅读 评论(0) 收藏
    【搜索引擎Jediael开发笔记3】使用HtmlParser提取网页中的链接 分类: H3_NUTCH 2014-05-20 20:50 1211人阅读 评论(0) 收藏
    Java解析HTML之HTMLParser使用与详解 分类: C_OHTERS 2014-05-19 21:46 2309人阅读 评论(0) 收藏
    【搜索引擎Jediael开发笔记2】使用HttpClient下载网页至本地文件 分类: C_OHTERS 2014-05-19 15:07 1108人阅读 评论(0) 收藏
    HttpClient基础教程 分类: C_OHTERS 2014-05-18 23:23 2600人阅读 评论(0) 收藏
    【搜索引擎基础知识2】网络爬虫的介绍 2014-05-16 14:10 395人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/hihocoder/p/11479293.html
Copyright © 2011-2022 走看看