【模板】POJ-1511(dijkstra堆优化+链式前向星)

POJ-1511

题目大意:

求1号点到各个点的最短距离,以及各个点到1号点的最短距离。

思路:

链式前向星+dijkstra堆优化

正反向存图+2次dijkstra

code:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000010;
const int INF = 0x3f3f3f3f;

struct Edge
{
    int to, dis, next;
};
Edge e[N << 1];
int head[N], dis[N], cnt;
Edge re[N << 1];
int rhead[N], rdis[N], rcnt;
bool vis[N];
int n, m, s;
LL ans;

void init() {
    ans = 0;
    s = 1; 
    memset(head, -1, sizeof(head));
    memset(rhead, -1, sizeof(rhead));
    for (int i = 1; i <= n; i++)
        dis[i] = rdis[i] = INF;
    cnt = rcnt = 0;
}

void add_Edge(int u, int v, int d)
{
    e[++cnt].dis = d;
    e[cnt].to = v;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void radd_Edge(int u, int v, int d)
{
    re[++rcnt].dis = d;
    re[rcnt].to = v;
    re[rcnt].next = rhead[u];
    rhead[u] = rcnt;
}

struct node
{
    int dis, pos;
    bool operator<(const node &x) const
    {
        return x.dis < dis;
    }
};


void dijkstra()
{
    memset(vis, 0, sizeof(vis));
    priority_queue<node> q;
    dis[s] = 0;
    q.push({0, s});
    while (!q.empty())
    {
        node tmp = q.top();
        q.pop();
        int x = tmp.pos;
        if (vis[x])
            continue;
        vis[x] = 1;
        for (int i = head[x]; ~i; i = e[i].next)
        {
            int y = e[i].to;
            if (dis[y] > dis[x] + e[i].dis)
            {
                dis[y] = dis[x] + e[i].dis;
                if (!vis[y])
                    q.push({dis[y], y});
            }
        }
    }
    for (int i = 1; i <= n; i++) ans += dis[i];
}

void rdijkstra()
{
    memset(vis, 0, sizeof(vis));
    priority_queue<node> q;
    rdis[s] = 0;
    q.push({0, s});
    while (!q.empty())
    {
        node tmp = q.top();
        q.pop();
        int x = tmp.pos;
        if (vis[x])
            continue;
        vis[x] = 1;
        for (int i = rhead[x]; ~i; i = re[i].next)
        {
            int y = re[i].to;
            if (rdis[y] > rdis[x] + re[i].dis)
            {
                rdis[y] = rdis[x] + re[i].dis;
                if (!vis[y])
                    q.push({rdis[y], y});
            }
        }
    }
    for (int i = 1; i <= n; i++) ans += rdis[i];
}

signed main()
{
    int T; scanf("%d", &T);
    while (T--) {
        scanf("%d %d", &n, &m);
        init();
        for (int i = 0; i < m; i++)
        {
            int u, v, w;
            scanf("%d %d %d", &u, &v, &w);
            add_Edge(u, v, w);
            radd_Edge(v, u, w);
        }
        dijkstra();
        rdijkstra();
        printf("%lld
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Nepenthe8/p/13646075.html