Bzoj 3694: 最短路 树链剖分
3694: 最短路
Time Limit: 5 Sec Memory Limit: 256 MB
Submit: 67 Solved: 34
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 1 3 1
1 4 2 1
2 1 6 0
2 3 4 0
5 2 3 0
3 2 2 1
5 3 1 1
3 5 2 0
4 5 4 0
Sample Output
HINT
对于100%的数据,n≤4000,m≤100000,1≤li≤100000
Source
#include<bits/stdc++.h>
using namespace std;
#define MAXN 4010
#define MAXM 100010
#define INF 1e9
struct node
{
int begin,end,value,next;
}edge[MAXN*];
struct NODE
{
int left,right,mn,tag;
}tree[MAXN*];
int cnt,Head[MAXN],n,size[MAXN],deep[MAXN],P[MAXN][],dis[MAXN],pos[MAXN],belong[MAXN],s1[MAXM],s2[MAXM],s3[MAXM],SIZE;
bool vis[MAXN];
void addedge(int bb,int ee,int vv)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].value=vv;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee,int vv)
{
addedge(bb,ee,vv);addedge(ee,bb,vv);
}
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
void dfs1(int u)
{
int i,v;
size[u]=;vis[u]=true;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(vis[v]==false)
{
deep[v]=deep[u]+;
dis[v]=dis[u]+edge[i].value;
P[v][]=u;
dfs1(v);
size[u]+=size[v];
}
}
}
void Ycl()
{
int i,j;
for(j=;(<<j)<=n;j++)
{
for(i=;i<=n;i++)
{
if(P[i][j-]!=-)P[i][j]=P[P[i][j-]][j-];
}
}
}
void dfs2(int u,int chain)
{
int k=,i,v;
pos[u]=++SIZE;belong[u]=chain;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&size[v]>size[k])k=v;
}
if(k==)return;
dfs2(k,chain);
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(deep[v]>deep[u]&&v!=k)dfs2(v,v);
}
}
int LCA(int x,int y)
{
int i,j;
if(deep[x]<deep[y])swap(x,y);
for(i=;(<<i)<=deep[x];i++);i--;
for(j=i;j>=;j--)if(deep[x]-(<<j)>=deep[y])x=P[x][j];
if(x==y)return x;
for(j=i;j>=;j--)
{
if(P[x][j]!=-&&P[x][j]!=P[y][j])
{
x=P[x][j];
y=P[y][j];
}
}
return P[x][];
}
void Build(int k,int l,int r)
{
tree[k].left=l;tree[k].right=r;tree[k].tag=INF;
if(l==r){tree[k].mn=INF;return;}
int mid=(l+r)/;
Build(k*,l,mid);
Build(k*+,mid+,r);
}
void Pushup(int k)
{
int l=k*,r=k*+;
tree[k].mn=min(tree[l].mn,tree[r].mn);
}
void Pushdown(int k)
{
int l=k*,r=k*+;
if(tree[k].tag!=INF)
{
tree[l].tag=min(tree[l].tag,tree[k].tag);
tree[r].tag=min(tree[r].tag,tree[k].tag);
tree[l].mn=min(tree[l].mn,tree[k].tag);
tree[r].mn=min(tree[r].mn,tree[k].tag);
tree[k].tag=INF;
}
}
void Change(int k,int l,int r,int C)
{
if(l<=tree[k].left&&tree[k].right<=r){tree[k].tag=min(tree[k].tag,C);tree[k].mn=min(tree[k].mn,C);return;}
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)Change(k*,l,r,C);
else if(l>mid)Change(k*+,l,r,C);
else {Change(k*,l,mid,C);Change(k*+,mid+,r,C);}
Pushup(k);
}
void Solve_change(int x,int f,int C)
{
while(belong[x]!=belong[f])
{
Change(,pos[belong[x]],pos[x],C);
x=P[belong[x]][];
}
if(x!=f)Change(,pos[f]+,pos[x],C);
}
int Query(int k,int l,int r)
{
if(l<=tree[k].left&&tree[k].right<=r)return tree[k].mn;
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(r<=mid)return Query(k*,l,r);
else if(l>mid)return Query(k*+,l,r);
else return min(Query(k*,l,mid),Query(k*+,mid+,r));
}
int Solve_query(int x,int f)
{
int MN=INF;
while(belong[x]!=belong[f])
{
MN=min(MN,Query(,pos[belong[x]],pos[x]));
x=P[belong[x]][];
}
if(x!=f)MN=min(MN,Query(,pos[f]+,pos[x]));
return MN;
}
int ask(int k,int lr)
{
if(tree[k].left==tree[k].right)return tree[k].mn;
Pushdown(k);
int mid=(tree[k].left+tree[k].right)/;
if(lr<=mid)return ask(k*,lr);
else return ask(k*+,lr);
}
int main()
{
int m,tot,i,a,b,l,t,lca,C;
n=read();m=read();
tot=;
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<=m;i++)
{
a=read();b=read();l=read();t=read();
if(t==)
{
s1[++tot]=a;s2[tot]=b;s3[tot]=l;
}
else addedge1(a,b,l);
}
memset(P,-,sizeof(P));SIZE=;
dfs1();Ycl();
dfs2(,);
Build(,,n);
//for(i=1;i<=n;i++)Change(1,pos[i],pos[i],dis[i]);
for(i=;i<=tot;i++)
{
lca=LCA(s1[i],s2[i]);
C=dis[s1[i]]+dis[s2[i]]+s3[i];
Solve_change(s1[i],lca,C);
Solve_change(s2[i],lca,C);
}
for(i=;i<=n;i++)
{
//t=Solve_query(i,1);
t=Query(,pos[i],pos[i]);
//t=ask(1,pos[i]);
if(t==INF)printf("-1 ");
else printf("%d ",t-dis[i]);
}
return ;
}
Bzoj 3694: 最短路 树链剖分的更多相关文章
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)
BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- NOIP 2015 BZOJ 4326 运输计划 (树链剖分+二分)
Description 公元 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− 条双向航道,每条航道建立在两个星球之间,这 n− 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司, ...
- BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分的点剖分+线段树.漏了一个小地方,调了一下午...... 还是要细心啊! 结 ...
随机推荐
- 九度OJ 1019 简单计算器 -- 2006年浙江大学计算机及软件工程研究生机试真题
题目地址:http://ac.jobdu.com/problem.php?pid=1019 题目描述: 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值. 输入: ...
- 程序员的编辑器——VIM
from:http://blog.chinaunix.net/uid-11278770-id-148579.html Chinaunix首页 | 论坛 | 认证专区 | 博客 登录 | 注册 ...
- android之调用webservice 实现图片上传
转:http://www.cnblogs.com/top5/archive/2012/02/16/2354517.html public void testUpload(){ try{ String ...
- [C#]async/Await 使用小计
如果指定使用 异步 或 异步 修饰符,方法是异步方法,可以实现以下两个函数. • 清单异步方法可以使用 Await 或指定的 等待 悬挂点. 等待运算符通知编译器异步方法不能继续点的过去,直到等待 ...
- 求和函数 sum详解
sum()的参数是一个list: >>> sum([1,2,3]) 6 >>> sum(range(1,3)) 3 还有一个比较有意思的用法 a = range(1 ...
- OpenCart框架运行流程介绍
框架运行流程介绍 这样的一个get请求http://hostname/index.php?route=common/home 发生了什么? 1. 开始执行入口文件index.php. 2. requi ...
- 【python】分片copy和等号的区别
例一 >>> list1=[1,2,3,4]>>> list2=list1>>> list3=list1[:]>>> list1 ...
- 在开发项目中有些常用的的实用代码(ps:平时看着无关紧要的,却很容易忘记)
1,在客户端使用Cookie document.cookie = "key=1"; document.cookie = "name=zhangsan"; coo ...
- Android引导界面
一.所需素材 很有必要整理一下,里面附带友盟的社会化分享组件,我就不去掉了. 二.代码 import com.umeng.update.UmengUpdateAgent; import a ...
- C# 判断系统空闲(键盘、鼠标不操作一段时间)
利用windows API函数 GetLastInputInfo()来判断系统空闲 //添加引用 using System.Runtime.InteropServices; // 创建结构体用于返回捕 ...