luogu 2934

同 bzoj3694

需要先求出最短路树

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>

const int N = 4e5 + 10, M = 4e5 + 10;

using namespace std;

struct Node {
    int u, v, w, nxt;
} G[M << 1], E[M << 1];
int n, m;
int head[N], now, js, dis[N];

#define gc getchar()

inline int read() {
    int x = 0; char c = gc;
    while(c < '0' || c > '9') c = gc;
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc;
    return x;
}

inline void write_int(int x) {
    printf("%d\n", x);
}

inline void Add(int u, int v, int w) {
    G[++ now].v = v, G[now].w = w, G[now].nxt = head[u], head[u] = now;
}

int fa[N], deep[N], topp[N], size[N], son[N], tree[N], Tree;

void Dfs_1(int u, int f_, int dep) {
    fa[u] = f_, deep[u] = dep, size[u] = 1;
    for(int i = head[u]; ~ i; i = G[i].nxt) {
        int v = G[i].v;
        if(v == f_) continue;
        dis[v] = dis[u] + G[i].w;
        Dfs_1(v, u, dep + 1);
        size[u] += size[v];
        if(size[v] > size[son[u]]) son[u] = v;
    }
}

void Dfs_2(int u, int tp) {
    topp[u] = tp, tree[u] = ++ Tree;
    if(!son[u]) return ;
    Dfs_2(son[u], tp);
    for(int i = head[u]; ~ i; i = G[i].nxt)
        if(G[i].v != fa[u] && G[i].v != son[u]) Dfs_2(G[i].v, G[i].v);
}

const int oo = 999999999;
int Minn[N << 2];

#define lson jd << 1
#define rson jd << 1 | 1

void Build_tree(int l, int r, int jd) {
    Minn[jd] = oo;
    if(l == r) return ;
    int mid = (l + r) >> 1;
    Build_tree(l, mid, lson), Build_tree(mid + 1, r, rson);
}

void Sec_G(int l, int r, int jd, int x, int y, int w) {
    if(x <= l && r <= y) {
        Minn[jd] = std:: min(Minn[jd], w);
        return ;
    }
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_G(l, mid, lson, x, y, w);
    if(y > mid)  Sec_G(mid + 1, r, rson, x, y, w);
}

void Sec_G_imp(int x, int y, int w) {
    int tpx = topp[x], tpy = topp[y];
    while(tpx != tpy) {
        if(deep[tpx] < deep[tpy]) std:: swap(tpx, tpy), std:: swap(x, y);
        Sec_G(1, n, 1, tree[tpx], tree[x], w);
        x = fa[tpx], tpx = topp[x];
    }
    if(x == y) return ;
    if(deep[x] < deep[y]) std:: swap(x, y);
    Sec_G(1, n, 1, tree[y] + 1, tree[x], w);
}

int Ans[N];

void Dfs_tree(int l, int r, int jd) {
    if(l == r) {
        Ans[l] = Minn[jd];
        return ;
    }
    int mid = (l + r) >> 1;
    Minn[lson] = std:: min(Minn[lson], Minn[jd]);
    Minn[rson] = std:: min(Minn[rson], Minn[jd]);
    Dfs_tree(l, mid, lson), Dfs_tree(mid + 1, r, rson);
}

int shead[N];
struct Node_2 {
    int u, v, w, id, nxt;
} sG[M << 1], sE[M << 1];
int stot = 0;
bool sOk[N];
queue <int> sQ;
int sdis[N]; 
bool svis[N];
int sto[N];

struct Short {

    void Link(int u, int v, int w, int id) {
        sG[++ stot].v = v, sG[stot].id = id, sG[stot].w = w, sG[stot].nxt = shead[u], shead[u] = stot;
    }
    
    void Spfa(int S) {
        for(int i = 1; i <= n; i ++) sdis[i] = oo;
        sdis[S] = 0;
        sQ.push(S);
        while(!sQ.empty()) {
            int stop = sQ.front();
            sQ.pop();
            svis[stop] = 0;
            for(int i = shead[stop]; ~ i; i = sG[i].nxt) {
                int v = sG[i].v;
                if(sdis[v] > sdis[stop] + sG[i].w) {
                    sdis[v] = sdis[stop] + sG[i].w;
                    sOk[sto[v]] = 0;
                    sto[v] = sG[i].id;
                    sOk[sto[v]] = 1;
                    if(svis[v] == 0) {
                        sQ.push(v);
                    }
                }
            }
        }
    }
    
    void Work() {
        for(int i = 1; i <= n; i ++) shead[i] = -1;
        for(int i = 1; i <= m; i ++) {
            int u = sE[i].u, v = sE[i].v, w = sE[i].w, id = sE[i].id;
            Link(u, v, w, id), Link(v, u, w, id);
        }
        Spfa(1);
    }
}AB;

int main() {
    n = read(), m = read();
    for(int i = 1; i <= n; i ++) head[i] = -1;
    for(int i = 1; i <= m; i ++) {
        int u = read(), v = read(), w = read();
        sE[i].u = u, sE[i].v = v; sE[i].w = w; sE[i].id = i;
    }
    if(Judge()) {
        
        return 0;
    } 
    AB.Work();
    int tot = 0;
    for(int i = 1; i <= m; i ++) {
        int u = sE[i].u, v = sE[i].v, w = sE[i].w; // id = sE[i].id;
        if(sOk[i] == 1) {
            Add(u, v, w), Add(v, u, w);
        } else {
            E[++ tot].u = u, E[tot].v = v; E[tot].w = w;
        }
    }
    Dfs_1(1, 0, 1);
    Dfs_2(1, 0);
    Build_tree(1, n, 1);
    for(int i = 1; i <= tot; i ++) {
        int x = E[i].u, y = E[i].v;
        Sec_G_imp(x, y, dis[x] + dis[y] + E[i].w);
    }
    Dfs_tree(1, n, 1);
    for(int i = 2; i <= n; i ++) {
        if(Ans[tree[i]] == oo) write_int(-1);
        else write_int(Ans[tree[i]] - dis[i]);
    }
    return 0;
}

 

posted @ 2018-09-09 20:06  xayata  阅读(145)  评论(0编辑  收藏  举报