BZOJ

看别人代码的时候发现哪一步都很眼熟,突然想起来,就在四个月前我好像看过还给别人讲过?mmp=v=

果然不写写就是容易忘。写了好歹忘了的时候还能复习呢(虽然和看别人的好像也没多少差别?)。


首先非加油站的点是没有用的。考虑如何删掉这些点然后在加油站之间连对应的边。

这里的一张图:

因为\(b<a\ \&\&\ b<c\),所以有\(b+c<a+c\ \&\&\ b+a<a+c\),也就是到一个点时,先去一次离它最近的点加油再去其它的点一定不会更差。记\(bel[p]\)为离\(p\)点最近的加油站,\(dis[p]\)为\(bel[p]\)到\(p\)的距离,对于一条边\((u,v,w)\),若\(bel[u]\neq bel[v]\),那么就在\(bel[u],bel[v]\)之间加一条\(dis[u]+dis[v]+w\)的边即可。(因为从任何一个点出发到了\(u\),先去一次\(bel[u]\)再去别的点不会更差,所以直接和\(bel[u]\)连边就行了)

具体就是以所有加油点为起点,\(Dijkstra\)跑一遍多源最短路。

然后求一遍最小生成树。询问就判断两点间路径上的最大值即可。

注意求生成树的时候可以直接按秩合并将树高保持在\(O(\log n)\)的高度。对于询问暴力跳\(fa\)即可。

要注意图可能不连通!!


//20216kb	2600ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define gc() getchar()
#define MAXIN 500000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=2e5+5; int Enum,H[N],nxt[N<<1],to[N<<1],len[N<<1],dis[N],bel[N],F[N],fa[N],w[N],rk[N],dep[N];
char IN[MAXIN],*SS=IN,*TT=IN;
std::priority_queue<pr> q;
struct Edge
{
int u,v,w;
bool operator <(const Edge &x)const
{
return w<x.w;
}
}e[N<<1];//双向边啊 inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int w,int v,int u)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, len[Enum]=w;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, len[Enum]=w;
}
int Dijkstra()
{
static bool vis[N];
int cnt=0;
while(!q.empty())
{
int x=q.top().second; q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=H[x],v; i; i=nxt[i])
if(dis[v=to[i]]>dis[x]+len[i])
dis[v]=dis[x]+len[i], bel[v]=bel[x], q.push(mp(-dis[v],v));
else if(bel[x]!=bel[v])
e[++cnt]=(Edge){bel[x],bel[v],dis[x]+dis[v]+len[i]};
}
return cnt;
}
int Find(int x)
{
return x==F[x]?x:F[x]=Find(F[x]);
}
void GetDep(int x)
{
if(fa[x]&&!dep[fa[x]]) GetDep(fa[x]);
dep[x]=dep[fa[x]]+1;
}
void Kruskal(const int n,const int m)
{
std::sort(e+1,e+1+m);
for(int i=1; i<=n; ++i) F[i]=i;
for(int i=1,r1,r2,k=1; i<=m; ++i)
{
if((r1=Find(e[i].u))==(r2=Find(e[i].v))) continue;
if(rk[r1]<rk[r2]) std::swap(r1,r2);//r2->r1
else if(rk[r1]==rk[r2]) ++rk[r1];
F[r2]=r1, fa[r2]=r1, w[r2]=e[i].w;
}
for(int i=1; i<=n; ++i) if(!dep[i]) GetDep(i);
}
inline bool Query()
{
int u=read(),v=read(),val=read();
if(Find(u)!=Find(v)) return 0;//!
if(dep[u]<dep[v]) std::swap(u,v);
for(int tmp=dep[v]; dep[u]>tmp; u=fa[u])
if(w[u]>val) return 0;
for(; u!=v; u=fa[u],v=fa[v])
if(w[u]>val||w[v]>val) return 0;
return 1;
} int main()
{
const int n=read(),s=read(),m=read();
memset(dis,0x7f,sizeof dis);
for(int i=1,x; i<=s; ++i) dis[x=read()]=0, bel[x]=x, q.push(mp(0,x));
for(int i=1; i<=m; ++i) AE(read(),read(),read());
int cnt=Dijkstra(); Kruskal(n,cnt);
for(int Q=read(); Q--; puts(Query()?"TAK":"NIE")); return 0;
}

BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)的更多相关文章

  1. BZOJ 4144: [AMPPZ2014]Petrol

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

  2. 【BZOJ 3732】 Network Kruskal重构树+倍增LCA

    Kruskal重构树裸题, Sunshine互测的A题就是Kruskal重构树,我通过互测了解到了这个神奇的东西... 理解起来应该没什么难度吧,但是我的Peaks连WA,,, 省选估计要滚粗了TwT ...

  3. BZOJ 4242: 水壶(Kruskal重构树 + Bfs)

    题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...

  4. bzoj 3545: [ONTAK2010]Peaks Kruskal重构树

    题目: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...

  5. BZOJ 5415: [Noi2018]归程(kruskal重构树)

    解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...

  6. [bzoj 3732] Network (Kruskal重构树)

    kruskal重构树 Description 给你N个点的无向图 (1 <= N <= 15,000),记为:1-N. 图中有M条边 (1 <= M <= 30,000) ,第 ...

  7. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  8. bzoj 3551 kruskal重构树dfs序上的主席树

    强制在线 kruskal重构树,每两点间的最大边权即为其lca的点权. 倍增找,dfs序对应区间搞主席树 #include<cstdio> #include<cstring> ...

  9. BZOJ.4793.[CERC2016]Hangar Hurdles(Kruskal重构树 BFS)

    题目链接 \(Description\) 有一个\(n\times n\)的正方形网格,上面有若干障碍点.\(q\)次询问,每次询问把一个正方形箱子从\((x1,y1)\)推到\((x2,y2)\) ...

随机推荐

  1. 你真的了解word-wrap和word-break的区别吗?

    这两个东西是什么,我相信至今还有很多人搞不清,只会死记硬背的写一个word-wrap:break-word;word-break:break-all;这样的东西来强制断句,又或者是因为这两个东西实在是 ...

  2. window.location的方法属性详解

    示例URL:http://b.a.com:88/index.php?name=kang&when=2011#first 属性 含义 值 protocol: 协议 "http:&quo ...

  3. MyRolan (快速启动小工具)

    类似 Rolan的快速启动工具. 启动后隐藏,当鼠标移至左上角时,窗口显示,点击项目可运行程序. GitHub地址: MyRolan . #if defined(UNICODE) && ...

  4. 实验吧 deeeeeeaaaaaadbeeeeeeeeeef-20

    题目描述: 图片是正确的吗? 解题思路: 这道题很有意思,常规的隐写思路没有线索,结果问题出现在照片的分辨率上,tEXtSource iPhone 5的后置摄像头是3264×2448的分辨率,前置摄像 ...

  5. DC综合简单总结(1)

     DC综合简单总结(1)  *****************set_dont_touch和set_dont_touch_network**************** ? 在综合的过程中,为了不让D ...

  6. JVM虚拟机和垃圾回收算法

    类加载机制 双亲委派模型 垃圾回收算法 CMS G1 类加载机制 双亲委派模型 双亲委派模型: 需要加载一个类,先委托父类加载,父类找父类,依次递归加载;加载不到再由自己加载 垃圾回收算法 JVM的内 ...

  7. ssh免密登陆:sshpass -p [passwd] ssh -p [port] root@192.168.X.X

    正文: ssh免密登陆:sshpass -p [passwd] ssh -p [port] root@192.168.X.X

  8. LaTex basics

    分节: \section{Supplemental Material}\label{sec:supplemental} 小节: \noindent {\bf Preparing References: ...

  9. 【原创】大叔经验分享(47)yarn开启日志归集

    yarn开启日志归集功能,除了配置之外 yarn.log-aggregation-enable=true 还要检查/tmp/logs目录是否存在以及权限,尤其是在开启kerberos之后,有些目录可能 ...

  10. Google 以 Flutter 作为原生突破口,移动端即将统一了

    Android 的前生今世 Android 系统 Android系统作为全球第一大系统,基于 Java 开发的移动端有着诸多的性能优势. 2018年前 H5 的性能瓶颈和 RN 的停更 导致业界对跨平 ...