zoukankan      html  css  js  c++  java
  • 最短路-Dijkstra算法整理

    维基说的很全面:https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

    理解:

      先设置访问数组vis[]和距离数组dist[],开始时把源点(source)先加入已访问数组(vis[source]=1),源点到源点的距离数组设为0(dist[source]=0);然后其它点到源点的dist[]为源点到该点的距离。然后找与源点相连的最近的点,并将其加入访问数组,再用这个点利用松弛操作更新其它未访问的点。循环执行顶点数-1次结束。

    下面代码假设源点为1,终点为N。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int maxn = 2000;
    int matrix[maxn][maxn];
    int vis[maxn], dist[maxn];
    int N, M;
    
    void Dijkstra(int source)
    {
        memset(vis, 0, sizeof(vis));
        vis[source] = 1;
        for (int i = 1; i <= N; i++) dist[i] = matrix[source][i];
    
        int cost, k;
        for (int i = 1; i < N; i++)
        {
            cost = INF;
            for (int j = 0; j <= N; j++)
            {
                if (!vis[j] && dist[j]<cost)
                {
                    cost = dist[j];
                    k = j;
                }
            }
    
            vis[k] = 1;
    
            for (int j = 0; j <= N; j++)
            {
                if (!vis[j] && matrix[k][j] != INF&&dist[j]>matrix[k][j] + cost)
                {
                    dist[j] = matrix[k][j] + cost;
                }
            }
    
        }
    }
    
    int main()
    {
        while (scanf("%d%d", &N, &M))
        {
            for (int i = 0; i <= N; i++)
                for (int j = 0; j <= N; j++)
                    if (i == j) matrix[i][j] = 0;
                    else matrix[i][j] = INF;
    
            for (int i = 0; i<M; i++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                matrix[u][v] = matrix[v][u] = w;
            }
            Dijkstra(1);
            printf("%d
    ", dist[N]);
        }
        return 0;
    }

    用优先队列和vector:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<vector>
    using namespace std;
    const int INF=0x3f3f3f3f;
    const int maxn=2000;
    struct Node
    {
        int num,dis;//num存储当前节点的编号,dis存储路径长度
        Node(){}
        Node(int a,int b){num=a;dis=b;}
        bool operator < (const Node& rhs)const{
            dis>rhs.dis;
        }
    };
    priority_queue<Node>que;
    vector<vector<Node> >v;
    int vis[maxn],dist[maxn];
    int N,M;
    
    void Dijkstra(int s)
    {
        for (int i=0;i<=N;i++) dist[i]=INF;
        dist[s]=0;
        que.push(Node(s,dist[s]));
        while(!que.empty())
        {
            Node p=que.top();que.pop();
            for (int i=0;i<v[p.num].size();i++)
            {
                Node q;
                q.num=v[p.num][i].num;
                if(dist[q.num]>dist[p.num]+v[p.num][i].dis)
                {
                    dist[q.num]=dist[p.num]+v[p.num][i].dis;
                    que.push(Node(q.num,dist[q.num]));
                }
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&N,&M);
        v.clear();
        v.resize(N+1);
        for (int i=0;i<M;i++)
        {
            int fr,to,w;
            scanf("%d%d%d",&fr,&to,&w);
            v[fr].push_back(Node(to,w));
            v[to].push_back(Node(fr,w));
    
        }
        Dijkstra(1);
        printf("%d
    ",dist[N]);
    }

     以hdu1874畅通工程续为例,一个pair较为偷懒的写法:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn = 1005;
     7 vector<pair<int, int> > E[maxn];
     8 int d[maxn];
     9 int n, m;
    10 
    11 void Dijkstra(int s)
    12 {
    13     priority_queue<pair<int, int> >Q;
    14     d[s] = 0;
    15     Q.push(make_pair(-d[s],s));
    16     while (!Q.empty())
    17     {
    18         int now = Q.top().second; Q.pop();
    19         for (int i = 0; i < E[now].size(); i++)
    20         {
    21             int v = E[now][i].first;
    22             if (d[v] > d[now] + E[now][i].second)
    23             {
    24                 d[v] = d[now] + E[now][i].second;
    25                 Q.push(make_pair(-d[v], v));
    26             }
    27         }
    28     }
    29 }
    30 
    31 int main()
    32 {
    33     while (scanf("%d%d",&n,&m)==2)
    34     {
    35         for (int i = 0; i < n; i++) E[i].clear();
    36         for (int i = 0; i < n; i++) d[i] = 1e9;
    37         for (int i = 0; i < m; i++)
    38         {
    39             int x, y, z;
    40             scanf("%d%d%d", &x, &y, &z);
    41             E[x].push_back(make_pair(y,z));
    42             E[y].push_back(make_pair(x, z));
    43         }
    44         int s, t;
    45         scanf("%d%d", &s, &t);
    46         Dijkstra(s);
    47         if (d[t] == 1e9)
    48             printf("-1
    ");
    49         else
    50             printf("%d
    ", d[t]);
    51     }
    52     return 0;
    53 }
  • 相关阅读:
    Django基础
    XSS BOT编写
    Weblogic ssrf+Redis Getshell学习
    CORS与JSONP配置不当所导致的信息泄露
    VulnHub FristLeaks 1.3
    攻防世界--REVERSE新手练习区writeup
    2019第三届强网杯线下3道RW
    SCTF2019--WEB 2题复现
    文件上传--利用.htaccess绕过黑名单
    CEF 与 QML 对比
  • 原文地址:https://www.cnblogs.com/zxhyxiao/p/7223886.html
Copyright © 2011-2022 走看看