分析:

Dijkstra求最短路树,在最短路树上进行操作,详情可见上一篇博客:http://www.cnblogs.com/Winniechen/p/9042937.html

我觉得这个东西不压行写出了有点丑...之后写了一个压行后更丑的...

附上压行后的代码:

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
using namespace std;
#define N 200005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define inf 0x3f3f3f3f
struct node
{
int to,next,val;
}E[N<<2],e[N<<1];
int head[N],head1[N],cnt,cnt1,fa[N],a[N];
int dep[N],anc[N],siz[N],son[N],idx[N],b[N];
int dis[N],minn[N<<2],cov[N<<2],n,vis[N],c[N];
void add1(int x,int y,int z){E[cnt1].to=y;E[cnt1].next=head1[x];E[cnt1].val=z;head1[x]=cnt1++;}
void add(int x,int y,int z){e[cnt].to=y;e[cnt].next=head[x];e[cnt].val=z;head[x]=cnt++;}
void Dijkstra()
{
memset(dis,0x3f,sizeof(dis));int num=0;
priority_queue<pair<int ,int > >q;dis[1]=0;q.push(make_pair(0,1));
while(!q.empty())
{
if(num==n)break;
int x=q.top().second;q.pop();
if(vis[x])continue;vis[x]=1;num++;
for(int i=head1[x];i!=-1;i=E[i].next)
{
int to1=E[i].to;
if(dis[to1]+E[i].val==dis[x])add(to1,x,E[i].val),add(x,to1,E[i].val);
}
for(int i=head1[x];i!=-1;i=E[i].next)
{
int to1=E[i].to;
if(dis[x]+E[i].val<dis[to1])
{
dis[to1]=dis[x]+E[i].val;
q.push(make_pair(-dis[to1],to1));
}
}
}
}
void dfs1(int x,int from)
{
fa[x]=from,dep[x]=dep[from]+1,siz[x]=1;
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(to1!=from)
{
dfs1(to1,x);siz[x]+=siz[to1];
if(siz[son[x]]<siz[to1])son[x]=to1;
}
}
}
int tims;
void dfs2(int x,int top)
{
anc[x]=top;idx[x]=++tims;
if(son[x])dfs2(son[x],top);
for(int i=head[x];i!=-1;i=e[i].next)
{
int to1=e[i].to;
if(to1!=fa[x]&&to1!=son[x])dfs2(to1,to1);
}
}
void PushDown(int rt)
{
if(cov[rt]!=inf)
{
int t=cov[rt];
cov[rt<<1]=min(cov[rt<<1],t);
minn[rt<<1]=min(minn[rt<<1],t);
cov[rt<<1|1]=min(cov[rt<<1|1],t);
minn[rt<<1|1]=min(minn[rt<<1|1],t);
cov[rt]=inf;
}
}
void build(int l,int r,int rt)
{
minn[rt]=cov[rt]=inf;
if(l==r)return ;int m=(l+r)>>1;
build(lson);build(rson);
}
void Update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
minn[rt]=min(minn[rt],c);cov[rt]=min(cov[rt],c);
return ;
}
PushDown(rt);int m=(l+r)>>1;
if(L<=m)Update(L,R,c,lson);
if(m<R)Update(L,R,c,rson);
}
int query(int x,int l,int r,int rt)
{
if(l==r)return minn[rt];
PushDown(rt);int m=(l+r)>>1;
if(m>=x)return query(x,lson);
else return query(x,rson);
}
void get_lca(int x,int y,int c)
{
while(anc[x]!=anc[y])
{
if(dep[anc[x]]<dep[anc[y]])swap(x,y);
Update(idx[anc[x]],idx[x],c,1,n,1);x=fa[anc[x]];
}
if(dep[x]>dep[y])swap(x,y);
if(x!=y)Update(idx[x]+1,idx[y],c,1,n,1);
}
int main()
{
int m;memset(head,-1,sizeof(head));memset(head1,-1,sizeof(head1));scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;scanf("%d%d%d",&x,&y,&z);
add1(x,y,z);add1(y,x,z);a[i]=x,b[i]=y,c[i]=z;
}
Dijkstra();dfs1(1,0);dfs2(1,1);build(1,n,1);
for(int i=1;i<=m;i++)
{
if(abs(dis[a[i]]-dis[b[i]])==c[i])continue;
get_lca(a[i],b[i],dis[a[i]]+dis[b[i]]+c[i]);
}
for(int i=2;i<=n;i++)
{
int t=query(idx[i],1,n,1);
t==inf?printf("-1\n"):printf("%d\n",t-dis[i]);
}
return 0;
}

  

[Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树的更多相关文章

  1. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  2. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  3. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  4. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  5. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  6. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  7. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  8. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  9. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

随机推荐

  1. java 中 printf()语句的理解

    对print和println的理解很简单,今天突然接触到printf(),有点懵,整理了下也帮自己理一理 printf是格式化输出的形式 下在举个例子: package other; public c ...

  2. angularjs作用域之transclude

    transclude是一个可选的参数.如果设置了,其值必须为true,它的默认值是false.嵌入有时被认为是一个高级主题,但某些情况下它与我们刚刚学习过的作用域之间会有非常好的配合.使用嵌入也会很好 ...

  3. IIR滤波器软件实现(Matlab+C++)

    使用C++来写一个IIR滤波器 我们首先要在MATLAB中设计一个IIR滤波器,并生成一个头文件,这个头文件中反映了IIR滤波器的频率响应特性 理论支持 IIR滤波叫做递归滤波器,它是一种具有反馈的滤 ...

  4. Linux的硬盘分区

    关于硬盘分区,这里先只讨论硬盘分区的方法在linux环境下,其他知识以后也会陆续说到 首先我们通过 df 命令查看一下硬盘的使用情况,在安装硬盘分区后做比较用 [root@bogon ~]# df - ...

  5. .net c#获取自定义Attribute

    前言: 在c#开发中,有时候我们需要读取 Attribute中的信息(关于Attribute , 我自己把他理解成一个可以为类,属性标记的东西,这个标记可以为你提供一些关于类,方法,属性的额外信息) ...

  6. 基于RecyclerView的瀑布流实现

    fragment的布局: <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...

  7. Ocelot中文文档-转换Headers

    Ocelot允许在请求下游服务之前和之后转换头部.目前Ocelot只支持查找和替换.这个功能在Github #190提出.我确定这个功能可以在各个方面发挥作用. 添加到请求 这个功能在GitHub # ...

  8. 在Java中谈尾递归--尾递归和垃圾回收的比较(转载)

    我不是故意在JAVA中谈尾递归的,因为在JAVA中谈尾递归真的是要绕好几个弯,只是我确实只有JAVA学得比较好,虽然确实C是在学校学过还考了90+,真学得没自学的JAVA好 不过也是因为要绕几个弯,所 ...

  9. JAVA之单源最短路径(Single Source Shortest Path,SSSP问题)dijkstra算法求解

    题目简介:给定一个带权有向图,再给定图中一个顶点(源点),求该点到其他所有点的最短距离,称为单源最短路径问题. 如下图,求点1到其他各点的最短距离 准备工作:以下为该题所需要用到的数据 int N; ...

  10. java.IO层次体系结构

    在整个Java.io包中最重要的就是5个类和一个接口.5个类指的是File.OutputStream.InputStream.Writer.Reader:一个接口指的是Serializable.掌握了 ...