zoukankan      html  css  js  c++  java
  • [SDOI2009]Elaxia的路线

    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
  • 相关阅读:
    项目alpha冲刺-测试
    项目Alpha冲刺--9/10
    项目Alpha冲刺--8/10
    项目Alpha冲刺--7/10
    项目Beta冲刺(1/7)(追光的人)(2019.5.23)
    Beta之前-凡事预则立(校园帮-追光的人)
    事后诸葛亮(追光的人)
    问题回答
    Alpha冲刺总结
    Alpha冲刺(10/10)——追光的人
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9249751.html
Copyright © 2011-2022 走看看