• 图论$cdot$最短路问题


    • Dijkstra单源最短路径算法

    Dijkstra可以计算出发点到每个点的最短路,及单源最短路径(SSSP)。这一特点使得Dijkstra常常用来进行其他算法的预处理。用Dijkstra算法计算最短路的代码如下:

    注:代码注释参见《算法竞赛入门经典——训练指南》(刘汝佳)

     1 struct Dijkstra{
     2     int n, m;
     3     vector<E> e;
     4     vector<int> G[maxn];
     5     bool done[maxn];
     6     int d[maxn];
     7     int p[maxn];
     8     void init(int n){
     9         this->n = n;
    10         FOR(i, 0, n - 1) G[i].clear();
    11         e.clear();
    12     }
    13     void addE(int from, int to, int dist){
    14         e.pb(E(from, to, dist));
    15         m = e.size();
    16         G[from].pb(m - 1);
    17     }
    18     void dijkstra(int s){
    19         priority_queue<HeapNode> Q;
    20         FOR(i, 0, n - 1) d[i] = int_inf;
    21         d[s] = 0;
    22         clr(done, 0);
    23         Q.push(HeapNode(0, s));
    24         while(!Q.empty()){
    25             HeapNode x = Q.top(); Q.pop();
    26             int u = x.u;
    27             if(done[u]) continue;
    28             done[u] = 1;
    29             int sz = G[u].size();
    30             FOR(i, 0, sz - 1){
    31                 E &y = e[G[u][i]];
    32                 if(d[y.to] > d[u] + y.dist){
    33                     d[y.to] = d[u] + y.dist;
    34                     p[y.to] = G[u][i];
    35                     Q.push(HeapNode(d[y.to], y.to));
    36                 }
    37             }
    38         }
    39     }
    40 };
    •  Bellman-Ford算法

    Bellman-Ford算法的一个重要应用是判负圈。在迭代$n-1$次后如果还可以进行松弛(relax)操作,说明一定存在负圈。如果采用队列实现,那么当某个结点入队了$n$次时可以判断出存在负圈,代码如下:

     1 struct Bellman_Ford{
     2     int n, m;
     3     vector<E> e;
     4     vector<int> G[maxn];
     5     bool inq[maxn];
     6     int d[maxn];
     7     int p[maxn];
     8     int cnt[maxn];
     9     void init(int n){
    10         this->n = n;
    11         FOR(i, 0, n - 1) G[i].clear();
    12         e.clear();
    13     }
    14     void addE(int from, int to, int dist){
    15         e.pb(E(from, to, dist));
    16         m = e.size();
    17         G[from].pb(m - 1);
    18     }
    19     bool negCyc(){
    20         queue<int> Q;
    21         clr(inq, 0), clr(cnt, 0);
    22         FOR(i, 0, n - 1) d[i] = 0, inq[i] = 1, Q.push(i);
    23         while(!Q.empty()){
    24             int u = Q.front(); Q.pop();
    25             inq[u] = 0;
    26             int sz = G[u].size();
    27             FOR(i, 0, sz - 1){
    28                 E &y = e[G[u][i]];
    29                 if(d[y.to] > d[u] + y.dist){
    30                     d[y].to = d[u] + y.dist;
    31                     p[e.to] = G[u][i];
    32                     if(!inq[y.to]){
    33                         Q.push(y.to);
    34                         inq[y.to] = 1;
    35                         if(++cnt[y.to] > n) return 1;
    36                     }
    37                 }
    38             }
    39         }
    40         return 0;
    41     }
    42 };
  • 相关阅读:
    day12——Python高阶函数及匿名函数
    day11——Python函数的一般形式、函数的参数
    day10——Python file操作
    day9——Python复习
    day8——Python if,while,for
    day7——Python的帮助
    day6——Python数据类型
    sqlserver执行sql文件命令(sqlcmd)
    数据库快照、游标、锁
    Linux 下根据进程名kill进程
  • 原文地址:https://www.cnblogs.com/astoninfer/p/5767118.html
Copyright © 2020-2023  润新知