最短路 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);
}

 

posted @ 2020-05-16 15:54  Jason66661010  阅读(286)  评论(0编辑  收藏  举报