zoukankan      html  css  js  c++  java
  • BZOJ 1726 [Usaco2006 Nov]Roadblocks第二短路:双向spfa【次短路】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1726

    题意:

      给你一个无向图,求次短路。

    题解:

      两种方法。

      

      方法一:

        一遍spfa,在spfa内维护最短路dis和次短路sec。

        分三种情况:

          (1)dis[now]可以更新dis[dest]。

          (2)dis[now]不能更新dis[dest],但dis[now]可以更新sec[dest]。

          (3)dis[now]不能更新dis[dest]和sec[dest],但sec[now]可以更新sec[dest]。

        分别处理即可。

      方法二:

        双向spfa。

        dis[i]表示从1到i的最短路,rev[i]表示从n到i的最短路。

        枚举每条边。找出最大的,但是比dis[n]小的dis[i] + len + rev[dest]的值,即为答案。

    AC Code(1):

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #include <queue>
      6 #define MAX_N 5005
      7 
      8 using namespace std;
      9 
     10 struct Edge
     11 {
     12     int dest;
     13     int len;
     14     Edge(int _dest,int _len)
     15     {
     16         dest=_dest;
     17         len=_len;
     18     }
     19     Edge(){}
     20 };
     21 
     22 int n,m;
     23 int dis[MAX_N];
     24 int sec[MAX_N];
     25 bool vis[MAX_N];
     26 vector<Edge> edge[MAX_N];
     27 queue<int> q;
     28 
     29 int get_front()
     30 {
     31     int now=q.front();
     32     q.pop();
     33     vis[now]=false;
     34     return now;
     35 }
     36 
     37 void insert(int now)
     38 {
     39     if(vis[now]) return;
     40     q.push(now);
     41     vis[now]=true;
     42 }
     43 
     44 void spfa(int start)
     45 {
     46     memset(dis,0x3f,sizeof(dis));
     47     memset(sec,0x3f,sizeof(sec));
     48     memset(vis,false,sizeof(vis));
     49     insert(start);
     50     dis[start]=0;
     51     while(!q.empty())
     52     {
     53         int now=get_front();
     54         for(int i=0;i<edge[now].size();i++)
     55         {
     56             Edge temp=edge[now][i];
     57             if(dis[temp.dest]>dis[now]+temp.len)
     58             {
     59                 sec[temp.dest]=min(dis[temp.dest],sec[now]+temp.len);
     60                 dis[temp.dest]=dis[now]+temp.len;
     61                 insert(temp.dest);
     62             }
     63             else if(dis[temp.dest]<dis[now]+temp.len && sec[temp.dest]>dis[now]+temp.len)
     64             {
     65                 sec[temp.dest]=dis[now]+temp.len;
     66                 insert(temp.dest);
     67             }
     68             else if(dis[temp.dest]==dis[now]+temp.len && sec[temp.dest]>sec[now]+temp.len)
     69             {
     70                 sec[temp.dest]=sec[now]+temp.len;
     71                 insert(temp.dest);
     72             }
     73         }
     74     }
     75 }
     76 
     77 void read()
     78 {
     79     cin>>n>>m;
     80     int a,b,v;
     81     for(int i=0;i<m;i++)
     82     {
     83         cin>>a>>b>>v;
     84         edge[a].push_back(Edge(b,v));
     85         edge[b].push_back(Edge(a,v));
     86     }
     87 }
     88 
     89 void solve()
     90 {
     91     spfa(1);
     92 }
     93 
     94 void print()
     95 {
     96     cout<<sec[n]<<endl;
     97 }
     98 
     99 int main()
    100 {
    101     read();
    102     solve();
    103     print();
    104 }

    AC Code(2):

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #include <queue>
      6 #define MAX_N 5005
      7 #define INF 10000000
      8 
      9 using namespace std;
     10 
     11 struct Edge
     12 {
     13     int dest;
     14     int len;
     15     Edge(int _dest,int _len)
     16     {
     17         dest=_dest;
     18         len=_len;
     19     }
     20     Edge(){}
     21 };
     22 
     23 int n,m;
     24 int ans=INF;
     25 int dis[MAX_N];
     26 int rev[MAX_N];
     27 bool vis[MAX_N];
     28 vector<Edge> edge[MAX_N];
     29 queue<int> q;
     30 
     31 int get_front()
     32 {
     33     int now=q.front();
     34     q.pop();
     35     vis[now]=false;
     36     return now;
     37 }
     38 
     39 void insert(int now)
     40 {
     41     if(vis[now]) return;
     42     q.push(now);
     43     vis[now]=true;
     44 }
     45 
     46 void spfa(int start,int *dis)
     47 {
     48     memset(dis,0x3f,sizeof(int)*MAX_N);
     49     memset(vis,false,sizeof(vis));
     50     insert(start);
     51     dis[start]=0;
     52     while(!q.empty())
     53     {
     54         int now=get_front();
     55         for(int i=0;i<edge[now].size();i++)
     56         {
     57             Edge temp=edge[now][i];
     58             if(dis[temp.dest]>dis[now]+temp.len)
     59             {
     60                 dis[temp.dest]=dis[now]+temp.len;
     61                 insert(temp.dest);
     62             }
     63         }
     64     }
     65 }
     66 
     67 void read()
     68 {
     69     cin>>n>>m;
     70     int a,b,v;
     71     for(int i=0;i<m;i++)
     72     {
     73         cin>>a>>b>>v;
     74         edge[a].push_back(Edge(b,v));
     75         edge[b].push_back(Edge(a,v));
     76     }
     77 }
     78 
     79 void solve()
     80 {
     81     spfa(1,dis);
     82     spfa(n,rev);
     83     for(int i=1;i<=n;i++)
     84     {
     85         for(int j=0;j<edge[i].size();j++)
     86         {
     87             Edge temp=edge[i][j];
     88             if(dis[i]+temp.len+rev[temp.dest]>dis[n])
     89             {
     90                 ans=min(ans,dis[i]+temp.len+rev[temp.dest]);
     91             }
     92         }
     93     }
     94 }
     95 
     96 void print()
     97 {
     98     cout<<ans<<endl;
     99 }
    100 
    101 int main()
    102 {
    103     read();
    104     solve();
    105     print();
    106 }
  • 相关阅读:
    Python爬虫实验报告之Big_Homework2_Douyu
    Python_dict
    Common sequence manipulation functions
    python基于opencv库的人脸识别总结
    使用cwrsync同步windows文件到linux
    搭建mosquitto
    docker搭建mqtt
    docker部署gofastdfs
    ap配置
    冒泡排序
  • 原文地址:https://www.cnblogs.com/Leohh/p/7631724.html
Copyright © 2011-2022 走看看