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 }

 

你可能感兴趣的:(最短路)