题目大意:太长了,略

Kruskal重构树,很神奇的一个算法吧

如果两个并查集被某种条件合并,那么这个条件作为一个新的节点连接两个并查集

那么在接下来的提问中,如果某个点合法,它的所有子节点也都合法,即子节点的限制少于父节点

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define inf 0x3f3f3f3f
#define ll long long
#define il inline
#define N 400100
#define M 800100
using namespace std;
//re
int T,cte,ctb,n,m,tot;
int head[N],hbt[M],fa[M],ff[M][],dis[N],use[N],mi[M],hei[M];
struct EDGE{int to,nxt,val;}edge[M];
struct Krs{int x,y,alt;}krs[N];
struct BT{int to,nxt;}bt[M*];
struct node{int id,dis;};
int cmpk(Krs s1,Krs s2){return s1.alt>s2.alt;}
il node ins(int x1,int x2){node kk;kk.id=x1,kk.dis=x2;return kk;}
bool operator<(const node &s1,const node &s2){return s1.dis>s2.dis;}
int find_fa(int x){
int fx=fa[x],pre;while(fx!=fa[fx])fx=fa[fx];
while(fa[x]!=fx){pre=fa[x],fa[x]=fx,x=pre;}
return fx;
}
int gc(){
int rett=,fh=;char p=getchar();
while(p<''||p>'') {if(fh=='-')fh=-;p=getchar();}
while(p>=''&&p<='') {rett=(rett<<)+(rett<<)+p-'';p=getchar();}
return rett*fh;
}
void clr()
{
cte=ctb=tot=;
memset(fa,,sizeof(fa));memset(ff,,sizeof(ff));
memset(krs,,sizeof(krs));memset(bt,,sizeof(bt));
memset(mi,0x3f,sizeof(mi));memset(edge,,sizeof(edge));
memset(head,-,sizeof(head));memset(hbt,-,sizeof(hbt));
}
void abt(int u,int v){
ctb++;bt[ctb].to=v;
bt[ctb].nxt=hbt[u],hbt[u]=ctb;
}
void ae(int u,int v,int w){
cte++;edge[cte].to=v,edge[cte].val=w;
edge[cte].nxt=head[u],head[u]=cte;
}
void dfs_bt(int x)
{
mi[x]=dis[x];
for(int j=hbt[x];j!=-;j=bt[j].nxt){
int v=bt[j].to;
if(v==ff[x][]) continue;
ff[v][]=v,ff[v][]=x;
dfs_bt(v);
mi[x]=min(mi[x],min(mi[v],dis[v]));
}
}
void get_multip(){
for(int j=;j<=;j++)
for(int i=;i<=tot;i++)
ff[i][j] = ff[ ff[i][j-] ][j-];
}
int multi(int x,int p){
for(int j=;j>=;j--){
if(hei[ff[x][j]]>p) x=ff[x][j];
}return x;
}
void dijkstra()
{
priority_queue<node>que;
memset(dis,0x3f,sizeof(dis));
memset(use,,sizeof(use));
dis[]=,que.push(ins(,));
while(!que.empty()){
node ss=que.top();que.pop();
if(use[ss.id]) continue;
use[ss.id]=;int x=ss.id;
for(int j=head[x];j!=-;j=edge[j].nxt){
int v=edge[j].to;
if(dis[v]>dis[x]+edge[j].val){
dis[v]=dis[x]+edge[j].val;
if(!use[v]) que.push(ins(v,dis[v]));
}
}
}
}
void Kruskal()
{
int fx,fy,sum=;tot=n;
for(int i=;i<=*n;i++) fa[i]=i;
sort(krs+,krs+m+,cmpk);
for(int i=;i<=m;i++){
fx=find_fa(krs[i].x),fy=find_fa(krs[i].y);
if(fx==fy) continue;
abt(++tot,fx),abt(tot,fy);
hei[tot]=krs[i].alt,sum++;
fa[fx]=tot,fa[fy]=tot;
if(sum==n-) break;
}hei[]=-;
dfs_bt(tot);
get_multip();
}
int solve(int x,int p)
{
int fx=multi(x,p);
return mi[fx];
} int main()
{
//freopen("data.in","r",stdin);
scanf("%d",&T);
while(T--)
{ n=gc(),m=gc();clr();
int x,y,w,z,lst=;
for(int i=;i<=m;i++)
{
x=gc(),y=gc(),w=gc(),z=gc();
ae(x,y,w),ae(y,x,w);
krs[i].x=x,krs[i].y=y,krs[i].alt=z;
}
dijkstra();
Kruskal();
int q,k,s;
q=gc(),k=gc(),s=gc();
for(int i=;i<=q;i++)
{
x=gc(),w=gc();
x=(x+k*lst-)%n+;
w=(w+k*lst)%(s+);
lst=solve(x,w);
printf("%d\n",lst);
} }
return ;
}

NOI 2018 归程 (Kruskal重构树)的更多相关文章

  1. NOI Day1T1归程(Kruskal重构树+Dijkstra)

    NOI Day1T1归程(Kruskal重构树+Dijkstra) 题目 洛谷题目传送门 题解 其实我不想写......,所以...... 挖个坑......我以后一定会补的 luogu的题解讲的还是 ...

  2. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

  3. [NOI2018]归程 kruskal重构树

    [NOI2018]归程 LG传送门 kruskal重构树模板题. 另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目. 题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经 ...

  4. [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)

    洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...

  5. 洛谷P4768 [NOI2018]归程(Kruskal重构树)

    题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...

  6. LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)

    LOJ2718 BZOJ5415 洛谷P4768 Rank3+Rank1无压力 BZOJ最初还不是一道权限题... Update 2019.1.5 UOJ上被hack了....好像是纯一条链的数据过不 ...

  7. #2718. 「NOI2018」归程 kruskal重构树

    链接 https://loj.ac/problem/2718 思路 我们希望x所在的连通块尽量的大,而且尽量走高处 离线的话可以询问排序,kruskal过程中更新答案 在线就要用kruskal重构树 ...

  8. loj2718 「NOI2018」归程[Kruskal重构树+最短路]

    关于Kruskal重构树可以翻阅本人的最小生成树笔记. 这题明显裸的Kruskal重构树. 然后这题限制$\le p$的边不能走,实际上就是要满足走最小边权最大的瓶颈路,于是跑最大生成树,构建Krus ...

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

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

随机推荐

  1. Project Euler 26 Reciprocal cycles( 分数循环节 )

    题意: 单位分数指分子为1的分数.分母为2至10的单位分数的十进制表示如下所示: 1/2 =  0.5 1/3 =  0.(3) 1/4 =  0.25 1/5 =  0.2 1/6 =  0.1(6 ...

  2. [POJ 3621] Sighting Cows

    01分数规划的基本裸题. 因为路线一定是个环,所以找个最优比率生成环即可 二分一个比值,check一下即可. #include <queue> #include <cstdio> ...

  3. Ubuntu环境搭建svn服务器

    记录一次使用Ubuntu环境搭建svn服务器的详细步骤 一.查看是否已经安装svn 命令:svn如果显示以下信息,说明已安装   二.卸载已安装的svn 命令:sudo apt-get remove ...

  4. Linux 程序包管理-YUM

    前端工具YUM管理程序包:  rpm管理软件虽然方便,但是需要手工解决软件包的依赖关系:很多时候安装一个软件需要首先安装一个或多个(有时多达上百个)其它软件,手工解决很复杂:使用yum可以解决这个问题 ...

  5. Python docs

    刚刚发现了Python好用的文档查询网页:Python docs,可以选择python版本查询,跟OpenCV docs很相似,很好用-

  6. fontend-githubs

    https://github.com/dypsilon/frontend-dev-bookmarks

  7. UVA 10593 Kites DP

    The season of flying kites is well ahead. So what? Let us make an inventory for kites. We are givena ...

  8. angular 兼容ie11 ie11兼容

    兼容一(new Date()用法) new Date('2018-01-01 00:00:00').getHours(); new Date('2018-01-01 00:00:00').getMin ...

  9. [jzoj 5661] 药香沁鼻 解题报告 (DP+dfs序)

    interlinkage: https://jzoj.net/senior/#contest/show/2703/0 description: solution: 注意到这本质就是一个背包,只是选了一 ...

  10. 7个好用的在线YouTube视频下载工具

    title: 7个好用的在线YouTube视频下载工具 toc: false date: 2018-10-10 15:11:00 categories: methods tags: youtube C ...