[Usaco2009 Jan]安全路经Travel BZOJ1576 Dijkstra+树链剖分+线段树
分析:
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+树链剖分+线段树的更多相关文章
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- 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 ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- 【转】H.264中的NAL技术
NAL技术 1.NAL概述 NAL全称Network Abstract Layer,即网络抽象层.在H.264/AVC视频编码标准中,整个系统框架被分为了两个层面:视频编码层面(VCL)和网络抽象层面 ...
- jjava Date格式是 May 07 17:44:06 CST 2018,怎么插入数据库中的timestamp格式中
首先 我来记录下错误 死在时间格式转换错误手里了 大致就是时间格式转化失败 java代码中的May 07 17:44:06 CST 2018 是这个格式转换为 数据库的 yyyy-MM-dd HH: ...
- Ubuntu16.04部署phantomjs的一个问题
首先phantomjs是作为pyspider的一个外部依赖组件部署的. apt安装完出现问题: QXcbConnection: Could not connect to display Phantom ...
- 彪悍开源的分析数据库-ClickHouse
https://zhuanlan.zhihu.com/p/22165241 今天介绍一个来自俄罗斯的凶猛彪悍的分析数据库:ClickHouse,它是今年6月开源,俄语社区为主,好酒不怕巷子深. 本文内 ...
- Codable实现json转Model,是时候干掉HandyJSON了!
自从开始使用Swift做项目,一直都在使用HandyJSON,不可否认,HandyJSON在Swift4.0是个好东西,也尝试过其它json转mode的工具,最终发现还是HandyJSON最好用. 去 ...
- java之MVC开发模式
友情提醒:eclipse创建servlet不会帮你同步创建一个web.xml配置文件:所以建议使用MyEclipse! 1.View层(jsp) <form action="javaw ...
- 安装vmware tool时出错
背景: 我想要在win10系统和vmware的ubuntu之间实现磁盘共享,从而实现文件共享.百度到可以通过安装vmware tools实现,所以着手安装vmware tools 问题: 安装vmwa ...
- 爬虫之urllib.error模块
error模块简介 我们在爬虫的时候发请求的时候难免出现错误,如访问不到服务器或者访问被禁止等等, 出错了之后urllib将错误信息封装成了一个模块对象中,这个模块就叫error模块 error的分类 ...
- C语言出来多久了你知道吗?
在20世纪80年代,为了避免不同开发者使用的C语言语法的差异,美国国家标准局为C语言开发了一套完整的美国国家标准语言文法,称为ANSI C,作为C语言的初始标准.. [1] 2011年12月8日,国际 ...
- Django+xadmin打造在线教育平台(九)
目录 在线教育平台(一) 在线教育平台(二) 在线教育平台(三) 在线教育平台(四) 在线教育平台(五) 在线教育平台(六) 在线教育平台(七) 在线教育平台( ...