hdu 1385 求字典序最小的最短路

需要注意的是这个题不仅有边权还有点权,起点和终点的点权不算。

思路还是一样,只是把路过的点的点权也加上再松弛即可。另外,距离相等的时候需要判断一下,选择字典序小的链连到这个点,方法就是把这个点以及之前的点放到栈里比较。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <stack>
  5 #include <cstdio>
  6 using namespace std;
  7 
  8 const int INF = 100000001;
  9 const int N = 10001;
 10 int graph[N][N];
 11 int dist[N];
 12 int tax[N];
 13 int pre[N];
 14 bool visit[N];
 15 int n, m;
 16 
 17 bool lessThan( int cur, int x, int y )
 18 {
 19     stack<int> sx, sy;
 20     //注意:cur必须也放到栈里
 21     sx.push(cur);
 22     sy.push(cur);
 23     while ( x != -1 )
 24     {
 25         sx.push(x);
 26         x = pre[x];
 27     }
 28     while ( y != -1 )
 29     {
 30         sy.push(y);
 31         y = pre[y];
 32     }
 33     while ( !sx.empty() && !sy.empty() )
 34     {
 35         if ( sx.top() != sy.top() ) return sx.top() < sy.top();
 36         sx.pop();
 37         sy.pop();
 38     }
 39     return sx.size() < sy.size();
 40 }
 41 
 42 void dij( int s, int t )
 43 {
 44     memset( visit, false, sizeof(visit) );
 45     for ( int i = 0; i <= n; i++ )
 46     {
 47         dist[i] = INF;
 48     }
 49     dist[s] = 0;
 50     pre[s] = -1;
 51     for ( int i = 1; i <= n; i++ )
 52     {
 53         int u = 0;
 54         for ( int j = 1; j <= n; j++ )
 55         {
 56             if ( !visit[j] && dist[j] < dist[u] )
 57             {
 58                 u = j;
 59             }
 60         }
 61         visit[u] = true;
 62         for ( int j = 1; j <= n; j++ )
 63         {
 64             if ( visit[j] ) continue;
 65             int d = dist[u] + graph[u][j] + tax[j];
 66             if ( d < dist[j] )
 67             {
 68                 dist[j] = d;
 69                 pre[j] = u;
 70             }
 71             else if ( d == dist[j] && lessThan( j, u, pre[j] ) )
 72             {
 73                 pre[j] = u;
 74             }
 75         }
 76     }
 77 }
 78 
 79 void out( int i )
 80 {
 81     if ( pre[i] == -1 )
 82     {
 83         printf("Path: %d", i);
 84     }
 85     else
 86     {
 87         out( pre[i] );
 88         printf("-->%d", i);
 89     }
 90 }
 91 
 92 int main ()
 93 {
 94     while ( scanf("%d", &n), n )
 95     {
 96         for ( int i = 1; i <= n; i++ )
 97         {
 98             for ( int j = 1; j <= n; j++ )
 99             {
100                 scanf("%d", &graph[i][j]);
101                 if ( graph[i][j] == -1 )
102                 {
103                     graph[i][j] = INF;
104                 }
105             }
106         }
107         for ( int i = 1; i <= n; i++ )
108         {
109             scanf("%d", tax + i);
110         }
111         int s, t;
112         while ( scanf("%d%d", &s, &t) != EOF )
113         {
114             if ( s == -1 || t == -1 ) break;
115             int tmp = tax[t];
116             tax[t] = 0;
117             dij( s, t );
118             tax[t] = tmp;
119             printf("From %d to %d :\n", s, t);
120             out( t );
121             printf("\nTotal cost : %d\n\n", dist[t]);
122         }
123     }
124     return 0;
125 }

 

posted @ 2015-07-22 11:53  hxy_has_been_used  阅读(319)  评论(0编辑  收藏  举报