【BZOJ1576】【Usaco2009】安全路经Travel(树链剖分+dijkstra)
2017-03-29 19:56
316 查看
Description
Input
第一行: 两个空格分开的数, N和M
第2..M+1行: 三个空格分开的数a_i, b_i,和t_i
Output
第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.
Sample Input
4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
Sample Output
3
3
6
题解:
BZOJ3694的加强版,必须用树剖。同时,要先用dijkstra求最小生成树。
BZOJ3694题解
本题代码如下:
Input
第一行: 两个空格分开的数, N和M
第2..M+1行: 三个空格分开的数a_i, b_i,和t_i
Output
第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.
Sample Input
4 5
1 2 2
1 3 2
3 4 4
3 2 1
2 4 3
Sample Output
3
3
6
题解:
BZOJ3694的加强版,必须用树剖。同时,要先用dijkstra求最小生成树。
BZOJ3694题解
本题代码如下:
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<queue> #include<vector> #define ll long long #define inf 0x7f7f7f7f #define N 100005 #define ls (rt<<1) #define rs (rt<<1|1) #define mid (l+r>>1) using namespace std; ll read() { ll x=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,tot,idx; int bin[20]; int u[N<<1],v[N<<1],w[N<<1]; int dis ,dep ,siz ,fa [20]; int pos ,bl ,hd ,from ; bool vis ,mark[N<<2]; struct nod { int to,nex,v; nod(){} nod(int a,int b,int c):to(a),v(b),nex(c){} }e[N<<2]; struct seg { int l,r,v,tag; }t[N<<2]; void addedge(int u,int v,int w) { e[++tot]=nod(v,w,hd[u]),hd[u]=tot; e[++tot]=nod(u,w,hd[v]),hd[v]=tot; } void dijk() { priority_queue<int,vector<int>,greater<int> > q; for(int i=2;i<=n;i++) dis[i]=inf; q.push(1); while(!q.empty()) { int now=q.top();q.pop(); if(vis[now]) continue; vis[now]=1; for(int i=hd[now];i;i=e[i].nex) if(dis[now]+e[i].v<dis[e[i].to]) { dis[e[i].to]=dis[now]+e[i].v; mark[from[e[i].to]]=0;from[e[i].to]=i;mark[i]=1; q.push(e[i].to); } } } void dfs1(int x,int f) { for(int i=1;i<=19 && bin[i]<=dep[x];i++) fa[x][i]=fa[fa[x][i-1]][i-1]; siz[x]=1; for(int i=hd[x];i;i=e[i].nex) { if(e[i].to==f || !mark[i]) continue; dep[e[i].to]=dep[x]+1; fa[e[i].to][0]=x; dfs1(e[i].to,x); siz[x]+=siz[e[i].to]; } } void dfs2(int x,int top) { bl[x]=top;pos[x]=++idx; int son=0; for(int i=hd[x];i;i=e[i].nex) if(mark[i] && dep[e[i].to]>dep[x] && siz[e[i].to]>siz[son]) son=e[i].to; if(son) dfs2(son,top); for(int i=hd[x];i;i=e[i].nex) if(mark[i] && dep[e[i].to]>dep[x] && e[i].to!=son) dfs2(e[i].to,e[i].to); } int lca(int x,int y) { if(dep[x]<dep[y]) swap(x,y); int t=dep[x]-dep[y]; for(int i=0;i<=19;i++) if(bin[i]&t) x=fa[x][i]; for(int i=19;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; if(x==y) return x; return fa[x][0]; } void build(int rt,int l,int r) { t[rt].l=l;t[rt].r=r;t[rt].tag=inf; if(l==r) { t[rt].v=inf; return; } build(ls,l,mid);build(rs,mid+1,r); } void pushdown(int rt) { if(t[rt].l==t[rt].r) return; t[ls].tag=min(t[ls].tag,t[rt].tag); t[rs].tag=min(t[rs].tag,t[rt].tag); if(t[ls].l==t[ls].r) t[ls].v=min(t[ls].v,t[rt].tag); if(t[rs].l==t[rs].r) t[rs].v=min(t[rs].v,t[rt].tag); t[rt].tag=inf; } void mdy(int rt,int L,int R,int v) { if(t[rt].tag!=inf) pushdown(rt); int l=t[rt].l,r=t[rt].r; if(L==l && R==r) { t[rt].tag=min(t[rt].tag,v); if(l==r) t[rt].v=min(v,t[rt].v); return; } if(R<=mid) mdy(ls,L,R,v); else if(L>mid) mdy(rs,L,R,v); else mdy(ls,L,mid,v),mdy(rs,mid+1,R,v); } int ask(int rt,int x) { if(t[rt].tag!=inf) pushdown(rt); int l=t[rt].l,r=t[rt].r; if(l==r) return t[rt].v; if(x<=mid) return ask(ls,x); else return ask(rs,x); } void solve(int x,int f,int v) { while(bl[x]!=bl[f]) { mdy(1,pos[bl[x]],pos[x],v); x=fa[bl[x]][0]; } if(x!=f) mdy(1,pos[f]+1,pos[x],v); } int main() { bin[0]=1; for(int i=1;i<=19;i++) bin[i]=bin[i-1]<<1; n=read(),m=read(); for(int i=1;i<=m;i++) { u[i]=read(),v[i]=read(),w[i]=read(); addedge(u[i],v[i],w[i]); } dijk(); dfs1(1,0);dfs2(1,1); build(1,1,n); for(int i=1;i<=m;i++) { int t=lca(u[i],v[i]); if(!mark[2*i]) solve(u[i],t,dis[u[i]]+dis[v[i]]+w[i]); if(!mark[2*i-1]) solve(v[i],t,dis[u[i]]+dis[v[i]]+w[i]); } for(int i=2;i<=n;i++) { int t=ask(1,pos[i]); if(t!=inf) printf("%d\n",t-dis[i]); else puts("-1"); } return 0; }
相关文章推荐
- BZOJ 1576: [Usaco2009 Jan]安全路经Travel【最短路树】【树链剖分】
- bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel【最短路树】【树链剖分】【线段树】
- BZOJ 1576: [Usaco2009 Jan]安全路经Travel( 树链剖分 )
- bzoj 1576 [Usaco2009 Jan]安全路经Travel(树链剖分,线段树)
- bzoj1576[Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra
- [BZOJ 1576] [Usaco2009 Jan] 安全路经Travel 【树链剖分】
- 【BZOJ】1576 [Usaco2009 Jan]安全路经Travel
- [BZOJ1576][Usaco2009 Jan]安全路径Travel(堆优化dijkstra+并查集)
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel(堆优化dijk + (并查集 || 树剖))
- bzoj1576 [Usaco2009 Jan]安全路经Travel(最短路径树+并查集)
- BZOJ1576 [Usaco2009 Jan]安全路经Travel
- 1576: [Usaco2009 Jan]安全路经Travel 最短路径树+树链剖分+线段树
- 【bzoj1576】【安全路径Travel】【dijkstra+树链剖分】
- 【bzoj1576】[Usaco2009 Jan]安全路经Travel
- bzoj 1576 [Usaco2009 Jan]安全路经Travel
- 【最短路径树+可并堆/树链剖分】BZOJ1576 [Usaco2009 Jan]安全路经Travel
- [Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树
- [删边最短路 并查集] BZOJ 1576 [Usaco2009 Jan]安全路经Travel