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; }