zoukankan      html  css  js  c++  java
  • [题解] poj 2449 Remmarguts' Date (dijkstra最短路+A*搜索)

    - 传送门 -

     http://poj.org/problem?id=2449

    #Remmarguts' Date

    | Time Limit: 4000MS |   | Memory Limit: 65536K |
    | Total Submissions: 30603 |   | Accepted: 8361 |

    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

    [[Submit](http://poj.org/submit?problem_id=2449)]   [[Status](http://poj.org/problemstatus?problem_id=2449)]   [[Discuss](http://poj.org/bbs?problem_id=2449)]

    - 题意 -

     求有向图中第k短路(可重复走).
     

    - 思路 -

     (A^*)算法的讲解: http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx
     
     本题中(A^*)的运用我觉得就是在优化BFS, 队列中的元素(x)我们设有ST[x]表示从起点出发到 x 点已走的路径, EN[x]表示 x 距离终点的最短路径. 则队列中元素按G[x] = ST[x]+EN[x]从小到大排列, 每次取出最小的G[x], 将 x 可以到达的点插入队列中(他们的路径是从 x 走到的, 依靠 G[x] 来更新这些点的G), 直到终点被取出第 k 次时有解(说明找到了 k 种不同路径通向终点).
     EN[x]要用反向边预处理最短路.
     
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define ft first
    #define sd second
    using namespace std;
    
    typedef pair<int, int> pii;
    const int N = 1e3 + 5;
    const int M = 1e5 + 5;
    
    int TO[M], NXT[M], V[M], HD[N];
    int re_TO[M], re_NXT[M], re_V[M], re_HD[N];
    int DIS[N], VIS[N];
    int n, m;
    int sz, re_sz;
    
    struct ASTAR {
    	int v, pos;
    	bool operator < (const ASTAR &tmp) const {
    		return DIS[v] + pos > DIS[tmp.v] + tmp.pos;
    	}
    };
    
    void add(int x, int y, int v) {
    	TO[++re_sz] = y; V[re_sz] = v;
    	NXT[re_sz] = HD[x]; HD[x] = re_sz;
    }
    
    void re_add(int x, int y, int v) {
    	re_TO[++sz] = y; re_V[sz] = v;
    	re_NXT[sz] = re_HD[x]; re_HD[x] = sz;
    }
    
    void dijkstra(int x) {
    	priority_queue<pii, vector<pii>, greater<pii> >Q;
    	memset(DIS, 0x3f, sizeof (DIS));
    	DIS[x] = 0;
    	pii st = make_pair(0, x);
    	Q.push(st);
    	while (!Q.empty()) {
    		pii x = Q.top();
    		Q.pop();
    		int u = x.sd;
    		if (VIS[u]) continue;
    		VIS[u] = 1;
    		for (int i = re_HD[u]; i; i = re_NXT[i]) {
    			int v = re_TO[i];
    			if (!VIS[v] && DIS[v] > DIS[u] + re_V[i]) {
    				DIS[v] = DIS[u] + re_V[i];
    				pii y = make_pair(DIS[v], v);
    				Q.push(y);
    			}
    		}
    	}
    }
    
    int astar(int x, int y, int k) {
    	if (x == y) k ++; //注意起点终点相同时, 一开始只有起点在队列中, 会被多计算一次.
    	priority_queue<ASTAR>Q;
    	ASTAR st;
    	st.v = x; st.pos = 0;
    	Q.push(st);
    	while (!Q.empty()) {
    		ASTAR x = Q.top();
    		Q.pop();
    		int u = x.v;
    		if (u == y) {
    			-- k;
    			if (!k)
    				return x.pos;
    		}
    		for (int i = HD[u]; i; i = NXT[i]) {
    			int v = TO[i];
    			ASTAR w;
    			w.v = v; w.pos = x.pos + V[i];
    			Q.push(w);
    		}
    	}
    	return -1;
    }
    
    int main() {
    	int x, y, v;
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; ++ i) {
    		scanf("%d%d%d", &x, &y, &v);
    		add(x, y, v);
    		re_add(y, x, v);
    	}
    	scanf("%d%d%d", &x, &y, &v);
    	dijkstra(y);
    	if (DIS[x] == 0x3f3f3f3f) {
    		printf("%d
    ", -1); //注意起点终点不连通的情况
    		return 0;
    	}
    	printf("%d
    ", astar(x, y, v));
    	return 0;
    }
    
  • 相关阅读:
    在进行页面的DIV CSS排版时,遇到IE6(当然有时Firefox下也会偶遇)浏览器中的图片元素img下出现多余空白的问题绝对是常见的对于该问题的解决方法也是“见机行事”。
    关于图片加载问题
    隐藏iframe边框
    设计模式-状态模式(State)
    软件设计原则
    设计模式-原型模式(Prototype)【重点:浅复制与深复制】
    设计模式-观察者模式(Observer)
    【Parallel】.Net 并行执行程序的使用心得
    个人对【依赖倒置(DIP)】、【控制反转(IOC)】、【依赖注入(DI)】浅显理解
    设计模式-建造者模式(Builder)
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7392069.html
Copyright © 2011-2022 走看看