首先用Dijkstra做出最短路生成树,设dis[p]为1到p点的最短路长度
对于一条不在生成树上的边u -> v,不妨设fa为u、v的lca
则一fa到v的路径上的任意点x都可以由u达到,走的方式是1 -> fa -> u -> v -> x,dis'[x] = dis[u] + dis(u, v) + dis[v] - dis[x]
于是可以用dis[u] + dis(u, v) + dis[v]更新fa到v的路径上的所有点
链剖一下,线段树lazytag就好了,连pushdown都不需要
1 /************************************************************** 2 Problem: 1576 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:2276 ms 7 Memory:16636 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 #include <queue> 13 14 using namespace std; 15 const int N = 1e5 + 5; 16 const int M = 2e5 + 5; 17 const int inf = 1e9; 18 19 struct edge { 20 int next, to, v, vis; 21 edge(int _n = 0, int _t = 0, int _v = 0, int __v = 0) : next(_n), to(_t), v(_v), vis(__v) {} 22 } e[M << 1]; 23 24 struct heap_node { 25 int v, e, to; 26 heap_node(int _v = 0, int _e = 0, int _t = 0) : v(_v), e(_e), to(_t) {} 27 28 inline bool operator < (const heap_node &p) const { 29 return v > p.v; 30 } 31 }; 32 33 struct tree_node { 34 int fa, sz, dep; 35 int top, son, e; 36 int w; 37 } tr[N]; 38 39 struct seg_node { 40 seg_node *ls, *rs; 41 int mn; 42 } *seg_root, *seg_null, mempool[N << 2], *cnt_seg = mempool; 43 44 int n, m, cnt_q; 45 int first[N], tot = 1; 46 int dis[N]; 47 priority_queue <heap_node> h; 48 49 inline int read() { 50 static int x; 51 static char ch; 52 x = 0, ch = getchar(); 53 while (ch < '0' || '9' < ch) 54 ch = getchar(); 55 while ('0' <= ch && ch <= '9') { 56 x = x * 10 + ch - '0'; 57 ch = getchar(); 58 } 59 return x; 60 } 61 62 inline void Add_Edges(int x, int y, int v) { 63 e[++tot] = edge(first[x], y, v), first[x] = tot; 64 e[++tot] = edge(first[y], x, v), first[y] = tot; 65 } 66 67 inline void add_to_heap(int p) { 68 static int x; 69 for (x = first[p]; x; x = e[x].next) 70 if (dis[e[x].to] == inf) 71 h.push(heap_node(e[x].v + dis[p], x, e[x].to)); 72 } 73 74 void Dijkstra(int S) { 75 int p; 76 for (p = 1; p <= n; ++p) dis[p] = inf; 77 while (!h.empty()) h.pop(); 78 dis[S] = 0, add_to_heap(S); 79 while (!h.empty()) { 80 if (dis[h.top().to] != inf) { 81 h.pop(); 82 continue; 83 } 84 p = h.top().to; 85 dis[p] = h.top().v, e[tr[p].e = h.top().e].vis = 1; 86 h.pop(), add_to_heap(p); 87 } 88 } 89 90 #define y e[x].to 91 #define Son tr[p].son 92 void dfs(int p) { 93 int x; 94 tr[p].sz = 1; 95 for (x = first[p]; x; x = e[x].next) 96 if (tr[y].e == x) { 97 tr[y].dep = tr[p].dep + 1; 98 dfs(y); 99 tr[p].sz += tr[y].sz; 100 if (Son == 0 || tr[y].sz > tr[Son].sz) Son = y; 101 } 102 } 103 104 void DFS(int p) { 105 int x; 106 tr[p].w = ++cnt_q; 107 if (Son) 108 tr[Son].top = tr[p].top, DFS(Son); 109 for (x = first[p]; x; x = e[x].next) 110 if (y != Son && tr[y].e == x) 111 tr[y].top = y, DFS(y); 112 } 113 #undef y 114 #undef Son 115 116 #define mid (l + r >> 1) 117 #define Ls p -> ls 118 #define Rs p -> rs 119 #define Mn p -> mn 120 inline void seg_make_null(seg_node *&p) { 121 p = cnt_seg, Ls = Rs = p, Mn = inf; 122 } 123 124 inline void seg_new(seg_node *&p) { 125 p = ++cnt_seg, *p = *seg_null; 126 } 127 128 void seg_build(seg_node *&p, int l, int r) { 129 seg_new(p); 130 if (l == r) return; 131 seg_build(Ls, l, mid), seg_build(Rs, mid + 1, r); 132 } 133 134 void seg_modify(seg_node *p, int l, int r, int L, int R, int v) { 135 if (L <= l && r <= R) { 136 Mn = min(Mn, v); 137 return; 138 } 139 if (L <= mid) seg_modify(Ls, l, mid, L, R, v); 140 if (mid + 1 <= R) seg_modify(Rs, mid + 1, r, L, R, v); 141 } 142 143 int seg_query(seg_node *p, int l, int r, int pos) { 144 if (l == r) return Mn; 145 return min(Mn, pos <= mid ? seg_query(Ls, l, mid, pos) : seg_query(Rs, mid + 1, r, pos)); 146 } 147 #undef mid 148 #undef Ls 149 #undef Rs 150 #undef Mn 151 152 int get_lca(int x, int y) { 153 while (tr[x].top != tr[y].top) { 154 if (tr[tr[x].top].dep < tr[tr[y].top].dep) swap(x, y); 155 x = tr[tr[x].top].fa; 156 } 157 if (tr[x].dep < tr[y].dep) swap(x, y); 158 return y; 159 } 160 161 void work_modify(int x, int fa, int v) { 162 while (tr[x].top != tr[fa].top) { 163 seg_modify(seg_root, 1, n, tr[tr[x].top].w, tr[x].w, v); 164 x = tr[tr[x].top].fa; 165 } 166 seg_modify(seg_root, 1, n, tr[fa].w + 1, tr[x].w, v); 167 } 168 169 int main() { 170 int i, x, y, z, fa, tmp; 171 n = read(), m = read(); 172 for (i = 1; i <= m; ++i) { 173 x = read(), y = read(), z = read(); 174 Add_Edges(x, y, z); 175 } 176 Dijkstra(1); 177 for (i = 2; i <= n; ++i) 178 tr[i].fa = e[tr[i].e ^ 1].to; 179 dfs(1); 180 tr[1].top = 1, DFS(1); 181 seg_make_null(seg_null); 182 seg_build(seg_root, 1, n); 183 #define y e[x].to 184 for (i = 1; i <= n; ++i) 185 for (x = first[i]; x; x = e[x].next) 186 if (!e[x].vis) work_modify(y, get_lca(i, y), dis[i] + dis[y] + e[x].v); 187 #undef y 188 for (i = 2; i <= n; ++i) { 189 tmp = seg_query(seg_root, 1, n, tr[i].w); 190 printf("%d\n", tmp == inf ? -1 : tmp - dis[i]); 191 } 192 return 0; 193 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen