「BZOJ3694」「FJ2014集训」最短路
首先树剖没得说了,这里说一下并查集的做法,
对于一条非树边,它会影响的点就只有u(i),v(i)到lca,对于lca-v的路径上所有点x,都可通过1-t-u-v-x,长度为dep[u]+dep[v]+w(i)-dep[x],lca-u同理,
将非树边按dep[u]+dep[v]+w(i)从小到大排序,显然每个点被前一条能更新他的边更新后即是最优解,此时将它与父亲节点合并,修改的时候用并查集向上修改即可。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define MP(a,b) make_pair(a,b)
#define MAXN 1000000
using namespace std;
int fa[MAXN],f[MAXN][20],dep[MAXN];
struct edge
{
int u,v,w,is,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define w(x) ed[x].w
#define is(x) ed[x].is
#define n(x) ed[x].nxt
friend bool operator < (edge a,edge b)
{
return a.is==b.is?(dep[a.u]+dep[a.v]+a.w)<(dep[b.u]+dep[b.v]+b.w):a.is<b.is;
}
}ed[MAXN];
int first[MAXN],num_e;
#define f(x) first[x]
int n,m,n0;
inline void add_e(int u,int v,int w,int t);
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int x,int ff,int deep)
{
f[x][0]=ff;dep[x]=deep;
for(int i=f(x);i;i=n(i))
if(v(i)!=ff && is(i))
dfs(v(i),x,deep+w(i));
}
int dis[MAXN];
signed main()
{
// freopen("in.txt","r",stdin); scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)fa[i]=i;
int ai,bi,wi,ti;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&ai,&bi,&wi,&ti);
add_e(ai,bi,wi,ti),add_e(bi,ai,wi,ti);
if(!ti)n0+=2;
}
dfs(1,0,0);
for(int i=1;i<20;i++)
for(int j=1;j<=n;j++)
f[j][i]=f[f[j][i-1]][i-1];
sort(ed+1,ed+m*2+1);dis[1]=0;
for(int i=1;i<=n0;i++)
{
int x=u(i),y=v(i);
while(x!=y)
{
if(dep[x]<dep[y])swap(x,y);
if(!dis[x])dis[x]=dep[u(i)]+dep[v(i)]+w(i)-dep[x];
fa[x]=f[x][0];
x=fa[x]=find(fa[x]);
}
}
for(int i=2;i<=n;i++)
printf("%d ",!dis[i]?-1:dis[i]);
}
inline void add_e(int u,int v,int w,int t)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
w(num_e)=w;
is(num_e)=t;
n(num_e)=f(u);
f(u)=num_e;
}
「BZOJ3694」「FJ2014集训」最短路的更多相关文章
- 「FJ2014集训」采药人的路径
啦啦啦 来写一篇题解 洛谷链接: P4930 「FJ2014集训」采药人的路径 统计路径?嗯往点分治上想. 把0和1转化为-1和1,求和完dis为0的路径就是阴阳平衡的路径了. 如果题目没有限制要有中 ...
- P4930「FJ2014集训」采药人的路径
题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这 ...
- 「2018山东一轮集训」 Tree
为什么出题人这么毒瘤啊??!!一个分块还要带log的题非要出成n<=2*1e5....... 为了卡过最后两个点我做了无数常数优化,包括但不限于:把所有线段树改成 存差分的树状数组:把树剖求LC ...
- 「2018山东一轮集训」Game
%%神仙题 首先转化一波模型:可以把原问题看成,初始每个位置有0/1个石子,1操作看成从一个位置拿走一个石子,2操作看成从l[i]拿走一个石子,并在[ l[i]+1 , r[i] ]的每个位置放上一个 ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- 「2017 山东一轮集训 Day5」苹果树
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
随机推荐
- @at-root和#{&}结合
Sass有脚本模式#{},他和&不同之处是,&只用作选择器,它只能出现在一个复合的开始选择器,类似于一个类型选择器,如a或者h1.但#{}他表示的是一个插值,它可以用在任何地方.同样的 ...
- Linux下读写UART串口的代码
Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- //////////////// ...
- Node.js调试技巧
1. console.log 跟前端调试相同,通过一步步打印相关变量进行代码调试 2. 使用Node.js内置的调试器 通过node debug xxx.js来进行调试: [root@~/wade/n ...
- 将自己的代码托管到github - 秦时明月 - CSDN博客
步骤: 1.建立自己的github 2.安装github客户端,并配置身份 3.建立github项目 4.将github项目库下载到本地 5.提交本地代码到github 详细操作: 1.github网 ...
- set的基本使用
构造一个集合 现在我们来构造一个集合. C++ 中直接构造一个 set的语句为: sets.这样我们定义了一个名为 s的.储存 T类型数据的 集合,其中 T是集合要储存的数据类型.初始的时候 s是空集 ...
- mac pro 1.5T内存是如何实现的
苹果发布全新Mac Pro:28核1.5T内存 预计售价10万+ 看到这样的新闻标题是不是很震撼,甚至怀疑人生,64位机怎么就可以1.5T内存了,自己的系统盘都没那么大 而且我们知道windows下的 ...
- 使用cnpm真的会有诡异的Bug
前端网页居然会出现堆栈溢出,然后网页崩溃,退出的问题. 出现这个Bug的时候,我非常的怀疑我自己的一些操作能力,比如,git的操作. 毕竟我是本地代码然后拉取远程分支,还会暂存自己的代码,然后暂存区代 ...
- 【水滴石穿】LoginScreen_Firabase_ReactNativeApp_Redux
先看效果 分析代码我们会发现,它使用了firebase 关于登陆部分应该是实时数据库,应该是他们后端校验的 //app.js //这里使用了实时数据库 import React, { Componen ...
- DOM查找元素的方法总结
按HTML查找:优点:范围可大可小,可设置条件:包括五种方式:1.按id查找:2.按标签名查找:var elems = parent.getElementsByTagName('');3.按name属 ...
- umount报错解决device is busy
umount –a 报错device is busy如图 df -h 执行 umount -l /dev/sdk1 fuser -m -v /cache10 再查看卸载了