zoukankan      html  css  js  c++  java
  • 最短路 P1629 邮递员送信 【反向图求最短路】

    题目

    https://www.luogu.com.cn/problem/P1629

    题目分析

    题目大意就是求节点1到各个点的最短路径以及各个点到节点1的最短路径,最后求和。

    节点1到各个点的最短路径:使用Dijkstra+堆优化即可实现(传送门

    但是各个点到节点1的最短路径如何求?

    这里注意:题目中的图是单向图,也就是说我们可以将求此图中的各个点到节点1的最短路径转换为求此图的反向图中的节点1到各个点的最短路径,这二者是等价的

    所以简单的方法就是两套Dijkstra——堆优化,一个在原图进行,一个在反向图中进行

    最后求和即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    #define maxn 1002
    #define maxm 100002
    #define inf 0x3f3f3f3f
    int n, m;
    struct edge
    {
        int to;
        int dis;
    
        int next;
    };
    struct node
    {
        int dis;
    
        int pos;
    };
    bool  operator <(const node &a, const  node &b)
    
    {
        return a.dis > b.dis;
    
    }
    edge e[maxm],e2[maxm];
    int head[maxn], dist[maxn], cnt=0, visited[maxn];
    int head2[maxn], dist2[maxn], cnt2 = 0, visited2[maxn];
    priority_queue<node>q, q2;
    void addedge(int u,int v,int w)
    {
        cnt++;
        e[cnt].to = v;
        e[cnt].dis = w;
        e[cnt].next = head[u];
        head[u] = cnt;
    }
    void addedge2(int u, int v, int w)
    {
        cnt2++;
        e2[cnt2].to = v;
        e2[cnt2].dis = w;
        e2[cnt2].next = head2[u];
        head2[u] = cnt2;
    }
    void Dijkstra(int s)
    {
        fill(dist, dist + n + 1, inf);
        dist[s] = 0;
        q.push({ 0, s });
        while (!q.empty())
        {
            node tmp = q.top(); q.pop();
            int x = tmp.pos;
            if (visited[x])continue;
            visited[x] = 1;
           for (int i = head[x]; i; i = e[i].next)
            {
                int y = e[i].to;
                if (dist[y] > dist[x] + e[i].dis)
    
                {
                    dist[y] = dist[x] + e[i].dis;
    
                    q.push({ dist[y], y });
                }
            }
        }
    
    }
    void FDijkstra(int s)
    {
        fill(dist2, dist2 + n + 1, inf);
        dist2[s] = 0;
        q2.push({ 0, s });
        while (!q2.empty())
        {
            node tmp = q2.top(); q2.pop();
            int x = tmp.pos;
            if (visited2[x])continue;
            visited2[x] = 1;
            for (int i = head2[x]; i; i = e2[i].next)
            {
                int y = e2[i].to;
                if (dist2[y] > dist2[x] + e2[i].dis)
    
                {
                    dist2[y] = dist2[x] + e2[i].dis;
    
                    q2.push({ dist2[y], y });
                }
            }
        }
    
    }
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < m; i++)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            addedge(a, b, c);
            addedge2(b, a, c);
        }
        Dijkstra(1);
        FDijkstra(1);
        long long answer = 0;
        for (int i = 2; i <= n; i++)
            answer += dist[i] + dist2[i];
    
        printf("%lld", answer);
    }
  • 相关阅读:
    文档翻译第002篇:Process Monitor帮助文档(Part 2)
    Hexo-设置阅读全文
    hexo 添加标签
    防御暴力破解SSH攻击
    Hexo NexT主题添加点击爱心效果
    【干货】2个小时教你hexo博客添加评论、打赏、RSS等功能 (转)
    svn命令在linux下的使用
    hexo 配置文件 实例
    Hexo安装配置详解
    markdown编辑
  • 原文地址:https://www.cnblogs.com/Jason66661010/p/12900844.html
Copyright © 2011-2022 走看看