山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 1576 [Usaco2009 Jan]安全路经Travel(树链剖分,线段树)

 

【题意】

 

    给定一个无向图,找到1-i所有的次短路经,要求与最短路径的最后一条边不重叠。

 

【思路】

 

    首先用dijkstra算法构造以1为根的最短路树。

    将一条无向边看作两条有向边,考察一条不在最短路树上的边(u,v),如果我们连接(u,v) ,设t=lct(u,v),则为v->t(不含t)路径上的点提供了另外一条1-x的路径且最后一条边不与最短路重合,这条路径长度为dis[u]+dis[v]+e.w-dis[x],对于每个点维护最小的mn=dis[u]+dis[v]+e.w,因为每次需要对一条路径进行修改,所以可以用树链剖分+线段树维护最小值和一个懒标记完成。

    好题。。。

   

【代码】

 

  1 #include<set>
  2 #include<cmath>
  3 #include<queue>
  4 #include<vector>
  5 #include<cstdio>
  6 #include<cstring>
  7 #include<iostream>
  8 #include<algorithm>
  9 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
 10 #define FOR(a,b,c) for(int a=(b);a<=(c);a++)
 11 using namespace std;
 12 
 13 typedef long long ll;
 14 const int N = 2e5+10;
 15 const int M = 4e5+10;
 16 const int inf = 1e9;
 17 
 18 ll read() {
 19     char c=getchar();
 20     ll f=1,x=0;
 21     while(!isdigit(c)) {
 22         if(c=='-') f=-1; c=getchar();
 23     }
 24     while(isdigit(c))
 25         x=x*10+c-'0',c=getchar();
 26     return x*f;
 27 }
 28 
 29 struct Edge {
 30     int u,v,w,nxt;
 31 }e[M];
 32 int en=1,front[N];
 33 void adde(int u,int v,int w) {
 34     e[++en]=(Edge){u,v,w,front[u]}; front[u]=en;
 35 }
 36 
 37 struct Node {
 38     int id,dis;
 39     bool operator < (const Node& rhs) const {
 40         return dis>rhs.dis;
 41     }
 42 };
 43 
 44 struct Tnode {
 45     int u,l,r,mn,tag;
 46     void minv(int x);
 47     void pushdown();
 48     void maintain();
 49 }T[N<<1];
 50 void Tnode::minv(int x) {
 51     tag=x;
 52     mn=min(mn,x);
 53 }
 54 void Tnode:: pushdown() {
 55     if(tag!=-1 && l!=r) {
 56         T[u<<1].minv(tag);
 57         T[u<<1|1].minv(tag);
 58         tag=-1;
 59     }
 60 }
 61 void Tnode:: maintain() {
 62     if(l==r) return ;
 63     mn=min(T[u<<1].mn,T[u<<1|1].mn);
 64 }
 65 
 66 priority_queue<Node> q;
 67 int n,m;
 68 int SZ,vis[N],dis[N],dep[N],siz[N],son[N],fa[N],top[N],mark[N],p[N],pl[N];
 69 
 70 void dijkstra()
 71 {
 72     FOR(i,0,n) dis[i]=inf;
 73     dis[1]=0;
 74     q.push((Node){1,0});
 75     while(!q.empty()) {
 76         int u=q.top().id; q.pop();
 77         if(vis[u]) continue;
 78         vis[u]=1;
 79         trav(u,i) {
 80             int v=e[i].v;
 81             if(dis[v]>dis[u]+e[i].w) {
 82                 dis[v]=dis[u]+e[i].w;
 83                 mark[p[v]]=0; mark[i]=1;
 84                 p[v]=i;
 85                 q.push((Node){v,dis[v]});
 86             }
 87         }
 88     }
 89 }
 90 void dfs1(int u)
 91 {
 92     siz[u]=1; son[u]=0;
 93     trav(u,i) if(mark[i]) {
 94         int v=e[i].v;
 95         if(v!=fa[u]) {
 96             fa[v]=u;
 97             dep[v]=dep[u]+1;
 98             dfs1(v);
 99             siz[u]+=siz[v];
100             if(siz[v]>siz[son[u]]) son[u]=v;
101         }
102     }
103 }
104 void dfs2(int u,int tp)
105 {
106     top[u]=tp; pl[u]=++SZ;
107     if(son[u]) dfs2(son[u],tp);
108     trav(u,i) if(mark[i]&&e[i].v!=fa[u])
109         dfs2(e[i].v,e[i].v);
110 }
111 int lca(int u,int v) {
112     while(top[u]!=top[v]) {
113         if(dep[top[u]]<dep[top[v]]) swap(u,v);
114         u=fa[top[u]];
115     }
116     return dep[u]<dep[v]? u:v;
117 }
118 void build(int u,int l,int r)
119 {
120     T[u]=(Tnode) {u,l,r,inf,-1};
121     if(l==r) return ;
122     int mid=l+r>>1;
123     build(u<<1,l,mid),
124     build(u<<1|1,mid+1,r);
125 }
126 void update(int u,int L,int R,int x)
127 {
128     T[u].pushdown();
129     if(L<=T[u].l&&T[u].r<=R) T[u].minv(x);
130     else {
131         int mid=T[u].l+T[u].r>>1;
132         if(L<=mid) update(u<<1,L,R,x);
133         if(mid<R)  update(u<<1|1,L,R,x);
134         T[u].maintain();
135     }
136 }
137 int query(int u,int x)
138 {
139     T[u].pushdown();
140     if(T[u].l==T[u].r) return T[u].mn;
141     else {
142         int mid=T[u].l+T[u].r>>1;
143         if(x<=mid) return query(u<<1,x);
144         else return query(u<<1|1,x);
145     }
146 }
147 
148 void modify(int u,int v,int x)
149 {
150     while(top[u]!=top[v]) {
151         if(dep[top[u]]<dep[top[v]]) swap(u,v);
152         update(1,pl[top[u]],pl[u],x);
153         u=fa[top[u]];
154     }
155     if(dep[u]>dep[v]) swap(u,v);
156     update(1,pl[u],pl[v],x);
157 }
158 
159 int main()
160 {
161     n=read(),m=read();
162     int u,v,w;
163     FOR(i,1,m) {
164         u=read(),v=read(),w=read();
165         adde(u,v,w),adde(v,u,w);
166     }
167     dijkstra();
168     dfs1(1),dfs2(1,1);
169     build(1,1,SZ);
170     for(int i=2;i<=en;i+=2) {
171         u=e[i].u,v=e[i].v,w=e[i].w;
172         int LCA=lca(u,v);
173         if(!mark[i]) modify(v,LCA,dis[u]+dis[v]+e[i].w);
174         if(!mark[i^1]) modify(u,LCA,dis[u]+dis[v]+e[i].w);
175     }
176     FOR(i,2,n) {
177         w=query(1,pl[i]);
178         if(w==inf) puts("-1");
179         else printf("%d\n",w-dis[i]);
180     }
181     return 0;
182 }

 

posted on 2016-03-27 09:34  hahalidaxin  阅读(407)  评论(0编辑  收藏  举报