POJ2449 Remmarguts' Date

题目链接:http://poj.org/problem?id=2449

题目描述:

  其实题目的大意就是求 第k短路, 存在就输出, 不存在就输出-1。 注意当起点和终点一致的时候,需要k++, 因为在OUTPUT时提到the length (time required) to welcome Princess Uyuw using the K-th shortest path。 可以看出是需要时间的,并且并没有描述相同点直接的时间为0这一条件,因此在计算路径的时候,为0的路径是不能够算到里面的; 而求最短路的时候会计算一次,因此需要k++。

  一般就是使用最短路+A*进行处理,A*可以直接使用优先队列进行维护即可。因为SPFA写残了, 调了好久。。。。、

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<queue>
  5 #include<vector>
  6 using namespace std ;
  7 /*
  8 题意就是求s->t 的第k短路, SPFA+A*
  9 SPFA写残了,调了好久~~~~
 10 */
 11 //
 12 const int MAX_NODE = 1005 ;
 13 const int MAX_EDGE = 1e5 + 5 ;
 14 const int INF = 1e7 ;
 15 int to[MAX_EDGE], next[MAX_EDGE], weight[MAX_EDGE], head[MAX_NODE] ;
 16 int dis[MAX_NODE] ;
 17 int edgeNum, s, t, k, n, m ;
 18 int ff[MAX_EDGE], tt[MAX_EDGE], ww[MAX_EDGE] ;
 19 queue <int> qu ;
 20 bool vis[MAX_NODE] ;
 21 //
 22 void clear(){
 23     edgeNum = 0 ;
 24     for( int i = 0; i < MAX_NODE; i++ ){
 25         head[i] = -1 ;
 26     }
 27 }
 28 //
 29 void addEdge(int u, int v, int w){
 30     to[edgeNum] = v ;
 31     weight[edgeNum] = w ;
 32     next[edgeNum] = head[u] ;
 33     head[u] = edgeNum++ ;
 34 }
 35 //
 36 void SPFA(){
 37     for( int i = 0; i <= n; i++ ){
 38         dis[i] = INF ;
 39         vis[i] = false ;
 40     }
 41     //cout << dis[n] << "   " << vis[n] << endl ;
 42     while( !qu.empty() )    qu.pop() ;
 43     qu.push(t) ;
 44     vis[t] = true ;
 45     dis[t] = 0 ;
 46     while( !qu.empty() ){
 47         int u = qu.front() ;
 48         qu.pop() ;
 49         vis[u] = false ;
 50         for( int edge = head[u]; edge != -1; edge = next[edge] ){
 51             if( dis[to[edge]] > dis[u]+weight[edge] ){
 52                 dis[to[edge]] = dis[u] + weight[edge] ;
 53                 if( !vis[to[edge]] ){
 54                     qu.push(to[edge]) ;
 55                     vis[to[edge]] = true ;
 56                 }
 57             }
 58         }
 59     }
 60 }
 61 //
 62 int solve(){
 63     clear() ;
 64     for( int i = 0; i < m; i++ ){
 65         addEdge(tt[i], ff[i], ww[i]) ;
 66     }
 67     SPFA() ;
 68     clear() ;
 69     for( int i = 0; i < m; i++ ){
 70         addEdge(ff[i], tt[i], ww[i]) ;
 71     }
 72     if( dis[s] == INF )    return -1 ;
 73     priority_queue < pair<int, int> > heap ;
 74     while( !heap.empty() )    heap.pop() ;
 75     heap.push(make_pair(-dis[s], s)) ;
 76     while( !heap.empty() ){
 77         int val = heap.top().first ;
 78         int u = heap.top().second ;
 79         int res = -val - dis[u] ;
 80         heap.pop() ;
 81         if( u == t ){
 82             if( !--k ){
 83                 return res ;
 84             }
 85         }
 86         for( int edge = head[u]; edge != -1; edge = next[edge] ){
 87             heap.push(make_pair(-(res+weight[edge]+dis[to[edge]]), to[edge])) ;
 88         } 
 89     }
 90     return -1 ;
 91 }
 92 //
 93 int main(){
 94     //freopen("1234.txt", "r", stdin) ;
 95     scanf("%d%d", &n, &m) ;
 96     int a, b, c ;
 97     for( int i = 0; i < m; i++ ){
 98         scanf("%d%d%d", &a, &b, &c) ;
 99         ff[i] = a ;    tt[i] = b ; ww[i] = c ;
100     }
101     scanf("%d%d%d", &s, &t, &k) ;
102     if( s == t )    k++ ;
103     cout << solve() << endl ;
104     return 0 ;
105 }

 

posted @ 2015-08-09 20:46  ct_usl  阅读(241)  评论(0编辑  收藏  举报