码迷,mamicode.com
首页 > 其他好文 > 详细

[SDOI2009]Elaxia的路线

时间:2018-07-01 12:27:52      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:--   怎么   spfa   lin   建图   分享   相互   style   中间   

P2149 [SDOI2009]Elaxia的路线

求无向图中,两对点间最短路的最长公共路径

 

喵啊…这题真心喵啊…orzorz

先spfa求出x1, y1, x2, y2的单源最短路

然后把x1到y1的最短路们建图

判断方式(精髓!):

        if(dis[0][uu] + ww + dis[1][vv] == dis[0][y1]){
            addedge(uu, vv, ww, 1);
            ind[vv]++;
        }

蒟蒻欲膜又止【划掉

 

注意 建完是有向图哦

 

在建完图之后 用同样的方式判断这个新图上有哪些边在x2-y2的最短路上 并标记

注意这里有个坑点 就是这两位小彩虹不一定要并肩走的…他们满足于相互呼唤… (* ̄︶ ̄* ) 

所以要判断一下正向和反向 只要有一个满足这条边就可以标记

那这里一段,那里一段怎么统计呢?

其实 同一条x2-y2最短路在新图上是连续的 因为如果中间有更短的地方 他们两个为什么不一起走另一条路呢?

所以最后按拓扑序bfs就好了

咱们能拓扑就别dfs 分分钟T爆…

技术分享图片
 1 int main(){
 2     init();
 3     spfa(x1, 0);
 4     spfa(y1, 1);
 5     spfa(x2, 2);
 6     spfa(y2, 3);
 7     int tmp = esize[0];
 8     for(int i = 1; i <= tmp; i++){
 9         int vv = edge[0][i].v, uu = edge[0][i].u, ww = edge[0][i].w;
10         if(dis[0][uu] + ww + dis[1][vv] == dis[0][y1]){
11             addedge(uu, vv, ww, 1);
12             ind[vv]++;
13         }
14     }
15     tmp = esize[1];
16     for(int i = 1; i <= tmp; i++){
17         int vv = edge[1][i].v, uu = edge[1][i].u, ww = edge[1][i].w;
18         if(dis[2][uu] + ww + dis[3][vv] == dis[2][y2] || dis[2][vv] + ww + dis[3][uu] == dis[2][y2])
19             flag[i] = 1;
20     }
21     bfs();
22     printf("%d", f[y1]);
23     return 0;
24 }
框架
技术分享图片
 1 inline void bfs(){
 2     q.push(x1);
 3     while(!q.empty()){
 4         int fro = q.front(); q.pop();        
 5         for(int i = head[1][fro]; i != -1; i = edge[1][i].next){
 6             int vv = edge[1][i].v, ww = edge[1][i].w;
 7             f[vv] = max(f[vv], f[fro] + flag[i] * ww);
 8             ind[vv]--;
 9             if(!ind[vv]) q.push(vv);
10         }
11     }
12 }
bfs
技术分享图片
 1 inline void spfa(int s, int tp){
 2     q.push(s);
 3     dis[tp][s] = 0;
 4     for(int i = 1; i <= n; i++) vis[i] = 0;
 5     while(!q.empty()){
 6         int fro = q.front(); q.pop(); vis[fro] = 0;
 7         for(int i = head[0][fro]; i != -1; i = edge[0][i].next){
 8             int vv = edge[0][i].v, ww = edge[0][i].w;
 9             if(dis[tp][vv] > dis[tp][fro] + ww){
10                 dis[tp][vv] = dis[tp][fro] + ww;
11                 if(!vis[vv]){
12                     q.push(vv);
13                     vis[vv] = 1;
14                 }
15             }
16         }
17     }
18 }
spfa

 

[SDOI2009]Elaxia的路线

标签:--   怎么   spfa   lin   建图   分享   相互   style   中间   

原文地址:https://www.cnblogs.com/hjmmm/p/9249751.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!