sdut 2498 AOE网上的关键路径 (最短路 算法)

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2498

题意:给定 一个 有向图  ,求出  从  图中只有 一个 入度为0 的点 s  和 一个  出度 为0 的 点 t 求 s 到t的  最长路径 若有 多条 输出 字典序最小的!

题解:

SPFA + 反向建图 。

对于 所要求的路径 ,s 的下一个点 是  与 s相连 且 距离 t 最长的点 ,若有 多个 选择序号 最小的 。

所以 自然 想到  求 各个点 到  t 的 最短距离 ,这样就 用到了 反向建图,并用 pre 记录的他的 前驱结点

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include<string>
 11 #define inf 99999999
 12 #define maxn 15000
 13 #define CL(a,b) memset(a,b,sizeof(a))
 14 #define  ll  long long
 15 //#define mx 1000010
 16 using namespace std;
 17 int n, m ,s,t;
 18 int in[maxn],out[maxn] ;
 19 struct node
 20 {
 21     int u ;
 22     int v;
 23     int w;
 24     int next;
 25 }p[maxn*4] ;
 26 int cnt ;
 27 int head[maxn] ;
 28 void add(int u,int v,int w)
 29 {
 30     p[cnt].u = u;
 31     p[cnt].v= v;
 32     p[cnt].w = w ;
 33     p[cnt].next = head[u] ;
 34     head[u] = cnt++ ;
 35 
 36 }
 37 queue<int>que;
 38 int dis[maxn],pre[maxn] ;
 39 int a[maxn] ;
 40 int vis[maxn] ;
 41 void solve()
 42 {
 43     int i ;
 44     for(i = 0; i <= n;i++)
 45     {
 46         dis[i] = -inf ;
 47         pre[i] = inf ;
 48     }
 49     while(!que.empty())que.pop() ;
 50 
 51     CL(vis, 0) ;
 52 
 53      dis[s] = 0 ;
 54     que.push(s) ;
 55     vis[s] = 1 ;
 56     while(!que.empty())
 57     {
 58         int u = que.front() ;que.pop() ;
 59          vis[u] = 0 ;
 60         for(i = head[u] ; i != -1;i = p[i].next)
 61         {
 62             int v = p[i].v ;
 63             int w = p[i].w ;
 64 
 65             if(dis[u] + w >= dis[v])
 66             {
 67                 if(dis[u] + w > dis[v])
 68                 {
 69                     dis[v] = dis[u] + w;
 70                     pre[v] = u ;
 71 
 72                     if(!vis[v])
 73                      que.push(v) ;
 74                 }
 75                 if(dis[u] + w == dis[v])
 76                 {
 77                     if(u < pre[v])
 78                     {
 79                         pre[v] = u ;
 80                         if(!vis[v])
 81                         que.push(v) ;
 82                     }
 83                 }
 84 
 85              }
 86 
 87         }
 88     }
 89 
 90 
 91     int num = 0;
 92     int tmp = t ;
 93     while(tmp != s)
 94     {
 95         a[num++] = tmp;
 96         tmp= pre[tmp] ;
 97     }
 98     a[num] = s;
 99 
100     printf("%d\n",dis[t]) ;
101     for(i = 0 ; i< num;i++)
102     {
103         printf("%d %d\n",a[i],a[i + 1]) ;
104     }
105 
106 
107 
108 }
109 int main()
110 {
111     int i ,x,y,d ;
112     while(scanf("%d%d",&n,&m)!=EOF)
113     {
114         cnt = 0 ;
115         CL(head, -1) ;
116 
117         for(i = 0 ; i<= n;i++)
118         {
119             out[i] = in[i] = 0 ;
120         }
121         for(i =0  ; i < m;i++)
122         {
123             scanf("%d%d%d",&x,&y,&d);
124             out[y]++;
125             in[x] ++ ;
126             add(y,x,d) ;
127 
128         }
129         for(i = 1; i <= n;i++)
130         {
131             if(in[i] == 0)
132                s = i;
133 
134             if(out[i] == 0)
135                t = i ;
136         }
137         solve() ;
138 
139 
140     }
141 }

 

posted @ 2012-12-08 10:40  Szz  阅读(626)  评论(0编辑  收藏  举报