首先用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 }
View Code

 

posted on 2015-04-17 22:41  Xs酱~  阅读(518)  评论(0编辑  收藏  举报