关键点的最小生成树?

关键点初始化为0,跑多源最短路,然后重构整个图,用Kruskal跑最小生成树

然后跑树链剖分在线回答询问

对树上每个点维护到链顶的最大值,结合线段树可以做到\(\Theta(n \log n)\)的复杂度

#include"cstdio"
#include"cstring"
#include"iostream"
#include"algorithm"
using namespace std; const int MAXN=1<<18; int n,m,s,np,root;
int x[MAXN],y[MAXN],z[MAXN],h[MAXN],c[MAXN],f[MAXN];
int blg[MAXN],hp[MAXN],id[MAXN],ln[MAXN],fa[MAXN],sn[MAXN];
int dep[MAXN],ren[MAXN],siz[MAXN],top[MAXN],val[MAXN],lis[MAXN];
int tree[MAXN<<1];
struct rpg{
int li,nx,ln;
}a[MAXN<<1];
struct lint{
int ls,nx,ln;
}line[MAXN]; inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||'9'<ch) ch=getchar();
while('0'<=ch&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x;
} void add(int ls,int nx,int ln)
{
a[++np]=(rpg){h[ls],nx,ln};h[ls]=np;
a[++np]=(rpg){h[nx],ls,ln};h[nx]=np;
} void init()
{
n=read(),s=read(),m=read();
for(int i=1;i<=s;++i) c[i]=read();
for(int i=1;i<=m;++i) x[i]=read(),y[i]=read(),z[i]=read(),add(x[i],y[i],z[i]);
return;
} void up(int x)
{
for(int i=x,j=i>>1;j;i=j,j>>=1){
if(ln[hp[i]]<ln[hp[j]]) swap(hp[i],hp[j]),swap(id[hp[i]],id[hp[j]]);
else break;
}return;
} void ins(int x)
{
hp[++hp[0]]=x;
id[x]=hp[0];
up(hp[0]);
return;
} void pop()
{
id[hp[1]]=0;
hp[1]=hp[hp[0]--];
id[hp[1]]=1;
for(int i=1,j=2;j<=hp[0];i=j,j<<=1){
if(j<hp[0]&&ln[hp[j+1]]<ln[hp[j]]) ++j;
if(ln[hp[i]]>ln[hp[j]]) swap(hp[i],hp[j]),swap(id[hp[i]],id[hp[j]]);
else break;
}return;
} void SPkstra()
{
memset(ln,0x7f,sizeof(ln));
for(int i=1;i<=s;++i) ln[c[i]]=0,ins(c[i]),blg[c[i]]=c[i];
while(hp[0]){
int nw=hp[1];pop();
for(int i=h[nw];i;i=a[i].li){
if(ln[a[i].nx]>ln[nw]+a[i].ln){
ln[a[i].nx]=ln[nw]+a[i].ln;
blg[a[i].nx]=blg[nw];
if(id[a[i].nx]) up(id[a[i].nx]);
else ins(a[i].nx);
}
}
}return;
} bool cmp(lint a,lint b){return a.ln<b.ln;}
int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
void un(int a,int b){int fa=find(a),fb=find(b);if(fa!=fb) f[fa]=fb;} void Krusbuild()
{
np=0;
memset(a,0,sizeof(a));
memset(h,0,sizeof(h));
for(int i=1;i<=m;++i) line[i]=(lint){blg[x[i]],blg[y[i]],ln[x[i]]+ln[y[i]]+z[i]};
for(int i=1;i<=n;++i) f[i]=i;
sort(line+1,line+m+1,cmp);
int ct=0;
for(int i=1;i<=m;++i){
if(find(line[i].ls)!=find(line[i].nx)){
un(line[i].ls,line[i].nx);
add(line[i].ls,line[i].nx,line[i].ln);
++ct;
}if(ct==s-1) break;
}return;
} void dfs1(int x,int f,int tp)
{
fa[x]=f;
dep[x]=tp;
siz[x]=1;
for(int i=h[x];i;i=a[i].li){
if(a[i].nx==f) continue;
dfs1(a[i].nx,x,tp+1);
val[a[i].nx]=a[i].ln;
siz[x]+=siz[a[i].nx];
if(siz[sn[x]]<siz[a[i].nx]) sn[x]=a[i].nx;
}return;
} void dfs2(int x,int tpx,int v)
{
id[x]=++id[0];
ren[id[x]]=val[x];
lis[x]=v;
top[x]=tpx;
if(!sn[x]) return;
dfs2(sn[x],tpx,max(v,val[sn[x]]));
for(int i=h[x];i;i=a[i].li){
if(a[i].nx==fa[x]||a[i].nx==sn[x]) continue;
dfs2(a[i].nx,a[i].nx,a[i].ln);
}return;
} void build(int k,int l,int r)
{
if(l==r){
tree[k]=ren[l];
return;
}int i=k<<1,mid=l+r>>1;
build(i,l,mid);build(i|1,mid+1,r);
tree[k]=max(tree[i],tree[i|1]);
return;
} void treecut()
{
id[0]=0;
for(int i=1;i<=s;++i) if(!dep[c[i]]) dfs1(c[i],c[i],1);
for(int i=1;i<=s;++i) if(!id[c[i]]) dfs2(c[i],c[i],0);
build(1,1,s);
return;
} int cask(int k,int l,int r,int le,int ri)
{
if(le<=l&&r<=ri) return tree[k];
int i=k<<1,mid=l+r>>1,maxn=0;
if(le<=mid) maxn=max(maxn,cask(i,l,mid,le,ri));
if(mid<ri) maxn=max(maxn,cask(i|1,mid+1,r,le,ri));
return maxn;
} int qmax(int x,int y)
{
int maxn=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
maxn=max(maxn,lis[x]);
x=fa[top[x]];
}if(dep[x]>dep[y]) swap(x,y);
if(id[x]+1<=id[y]) maxn=max(maxn,cask(1,1,s,id[x]+1,id[y]));
return maxn;
} void solve()
{
m=read();
while(m--){
int x=read(),y=read(),d=read();
if(find(x)!=find(y)||qmax(x,y)>d) puts("NIE");
else puts("TAK");
}return;
} int main()
{
init();
SPkstra();
Krusbuild();
treecut();
solve();
return 0;
}

[AMPPZ2014]Petrol的更多相关文章

  1. BZOJ 4144: [AMPPZ2014]Petrol

    4144: [AMPPZ2014]Petrol Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 457  Solved: 170[Submit][Sta ...

  2. 4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)

    4144: [AMPPZ2014]Petrol Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 752  Solved: 298[Submit][Sta ...

  3. 【BZOJ4144】[AMPPZ2014]Petrol 最短路+离线+最小生成树

    [BZOJ4144][AMPPZ2014]Petrol Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油 ...

  4. 【BZOJ4144】[AMPPZ2014]Petrol(最短路+最小生成树+并查集)

    Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满. q次询问,每次给出x,y,b,表示出发点是 ...

  5. 【BZOJ】4144: [AMPPZ2014]Petrol

    题意 给定一个\(n\)个点.\(m\)条边的带权无向图,其中有\(s\)个点是加油站.每辆车都有一个油量上限\(b\),即每次行走距离不能超过\(b\),但在加油站可以补满.\(q\)次询问,每次给 ...

  6. BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)

    BZOJ 看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v= 果然不写写就是容易忘.写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?). 首 ...

  7. [BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]

    题意 题目链接 分析 假设在 \(a \rightarrow b\) 的最短路径中出现了一个点 \(x\) 满足到 \(x\) 最近的点是 \(c\) ,那么我们完全可以从 \(a\) 直接走到 \( ...

  8. BZOJ4144: [AMPPZ2014]Petrol(最短路 最小生成树)

    题意 题目链接 Sol 做的时候忘记写题解了 可以参考这位大爷 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  9. bzoj4144 [AMPPZ2014]Petrol

    link 题意: 给一个n个点m条边的带权无向图,其中k个点是加油站,每个加油站可以加满油,但不能超过车的油量上限.有q个询问,每次给出x,y,b,保证x,y都是加油站,问一辆油量上限为b的车从x出发 ...

随机推荐

  1. 【wireshark】开发环境搭建

    1. 引言 本文相关内容可参考Wireshark开发指南第2章”Quick Setup” 要对wireshark代码进行修改,除了下文介绍的lua插件的方式以外,都需要对wirehshark源码进行编 ...

  2. JMeter性能测试-服务器资源监控插件详解

          零.引言 我们对被测应用进行性能测试时,除了关注吞吐量.响应时间等应用自身的表现外,对应用运行所涉及的服务器资源的使用情况,也是非常重要的方面,通过实时监控,可以准确的把握不同测试场景下服 ...

  3. Python小白学习之路(十四)—【作用域】【匿名函数】【编程方法论】【高阶函数】

    吧啦吧啦内心戏 在没有具体学作用域之前,我在之前的学习笔记中就有提到 我开始以为是自己自创的词儿 没想到这个词早已经存在(手动捂脸) 真是个无知的小火锅(不知者无罪) 我发现自己最擅长做的事情,就是给 ...

  4. 【2018北京集训十二】 coin 矩阵快速幂

    矩阵快速幂原来还可以这么用?? 你们城里人还真会玩. 我们令$f[i][j][k]$表示总的钱数为i,当前使用的最大面值硬币的面值为$v_j$,最小为$v_k$的方案数量. 不难发现$f[i][j][ ...

  5. Swift的Guard语句

    与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行.与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码.你可以把guard近似的看做是Assert,但 ...

  6. R软件常用命令

    1.getwd()      获取默认的目录 2.> mydata <- read.csv("1.csv")  读取1.csv文件中的数据,并赋值给一个mydata的对 ...

  7. shell脚本批量部署ssh

    日常运维工作中,需要给几十上百台服务器批量部署软件或者是重启服务器等操作, 这样大量重复性的工作一定很苦恼,本文给大家提供了最基本的批量操作的方法,虽然效率不高,对于初学者来说还是好理解.由于刚开始学 ...

  8. 编译vs下可调试的ffmpeg和x264

    以前随手记的笔记,翻出来,整理下哈 ffmpeg 在windows上的编译还是比较麻烦的,而且如果mingw-gcc编译的话,是无法在vs下调试的 所以以前刚开始玩ffmpeg的时候,费了一些功夫,用 ...

  9. ubuntu16.04更改源为阿里源

    一.通过系统更换源 第一步:备份原来的源文件cd /etc/apt/  然后会显示下面的源文件sources.list输入命令sudo cp sources.list sources.list.bak ...

  10. 《Mysql技术内幕,Innodb存储引擎》——Innodb体系结构

    Innodb体系结构 Innodb存储引擎主要包括内存池以及后台线程. 内存池:多个内存块组成一个内存池,主要维护进程/线程的内部数据.缓存磁盘数据,修改文件前先修改内存.redo log 后台线程: ...