bzoj2594 [Wc2006]水管局长数据加强版——LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2594
时间倒序一下,就是 魔法森林 那道题;
有个不解的地方,是 access 里面关于 pushup 的地方,两种写法都可以,但不明白没有注释掉的写法为什么也可以。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int const maxn=,maxm=1e6+;
int n,m,Q,val[maxn],mx[maxn],fa[maxn],pre[maxn],c[maxn][],sta[maxn],rev[maxn];
struct N{int hd,to,w,id; bool b;}edge[maxm];
struct T{int u,v,ans,f,id;}q[];
bool cmp(N x,N y){return x.w<y.w;}
bool cmp2(N x,N y){return x.hd<y.hd || (x.hd==y.hd && x.to<y.to);}
bool cmpp(N x,N y){return x.id<y.id;}
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return ret*f;
}
int get(int x,int y)
{
int l=,r=m;
while(l<=r)
{
int mid=((l+r)>>);
if(edge[mid].hd==x && edge[mid].to==y)return mid;
if(edge[mid].hd<x || (edge[mid].hd==x && edge[mid].to<y))l=mid+;
else r=mid-;
}
}
bool isroot(int x)
{
return c[pre[x]][]!=x && c[pre[x]][]!=x;
}
void pushup(int x)
{
int ls=c[x][],rs=c[x][];
mx[x]=x;
if(val[mx[ls]]>val[mx[x]])mx[x]=mx[ls];
if(val[mx[rs]]>val[mx[x]])mx[x]=mx[rs];
}
void reverse(int x)
{
int ls=c[x][],rs=c[x][];
if(rev[x])
{
rev[ls]^=; rev[rs]^=; rev[x]=;
swap(c[x][],c[x][]);
}
}
void rotate(int x)
{
int y=pre[x],z=pre[y],d=(c[y][]==x);
if(!isroot(y))c[z][c[z][]==y]=x;
pre[x]=z; pre[y]=x; pre[c[x][!d]]=y;
c[y][d]=c[x][!d]; c[x][!d]=y;
pushup(y); pushup(x);
}
void splay(int x)
{
int top=; sta[++top]=x;
for(int i=x;!isroot(i);i=pre[i])sta[++top]=pre[i];
for(int i=top;i;i--)reverse(sta[i]);
for(;!isroot(x);rotate(x))
{
int y=pre[x],z=pre[y];
if(isroot(y))continue;
((c[y][]==x)^(c[z][]==y))?rotate(x):rotate(y);
}
pushup(x);//和下面配套
}
void access(int x)
{
for(int t=;x;c[x][]=t,t=x,x=pre[x])splay(x);//这样为什么也可以?
}
//void access(int x)
//{
// int t=0;
// while(x)
// {
// splay(x);c[x][1]=t;pushup(x);t=x;x=pre[x];
// }
//}
void makeroot(int x)
{
access(x); splay(x); rev[x]^=;
}
void link(int x,int y)
{
makeroot(x); pre[x]=y;//
}
void cut(int x,int y)
{
makeroot(x); access(y); splay(y);
pre[x]=; c[y][]=;
}
int query(int x,int y)
{
makeroot(x); access(y); splay(y); return mx[y];
}
int main()
{
n=rd(); m=rd(); Q=rd();
for(int i=;i<=n;i++)fa[i]=i;
for(int i=;i<=m;i++)
{
edge[i].hd=rd(); edge[i].to=rd(); edge[i].w=rd();
if(edge[i].hd>edge[i].to)swap(edge[i].hd,edge[i].to);
}
sort(edge+,edge+m+,cmp);//w
for(int i=;i<=m;i++)
{
edge[i].id=i;
val[i+n]=edge[i].w; mx[i+n]=i+n;//
}
sort(edge+,edge+m+,cmp2);//u,v
for(int i=;i<=Q;i++)
{
q[i].f=rd(); q[i].u=rd(); q[i].v=rd();
if(q[i].f==)
{
if(q[i].u>q[i].v)swap(q[i].u,q[i].v);
int t=get(q[i].u,q[i].v);
// edge[t].b=1; q[i].id=edge[i].id;
edge[t].b=; q[i].id=edge[t].id;
}
}
sort(edge+,edge+m+,cmpp);//w
for(int i=,tot=;i<=m;i++)
{
if(edge[i].b)continue;//kruskal 连不删的边
int u=edge[i].hd,v=edge[i].to;
if(find(u)!=find(v))
{
fa[find(u)]=find(v);
link(u,i+n); link(v,i+n);
tot++;
if(tot==n-)break;
}
}
for(int i=Q;i;i--)
{
int u=q[i].u,v=q[i].v;
if(q[i].f==)q[i].ans=val[query(u,v)];
else
{
int k=q[i].id,t=query(u,v);
if(edge[k].w<val[t])
{
cut(t,edge[t-n].hd); cut(t,edge[t-n].to);
link(u,k+n); link(v,k+n);
}
}
}
for(int i=;i<=Q;i++)
if(q[i].f==)printf("%d\n",q[i].ans);
return ;
}
bzoj2594 [Wc2006]水管局长数据加强版——LCT的更多相关文章
- [bzoj2594][Wc2006]水管局长数据加强版 (lct)
论蒟蒻的自我修养T_T.. 和noi2014魔法森林基本一样...然而数据范围大得sxbk...UPD:这题如果用lct判联通的话可能会被卡到O(mlogm)..所以最好还是用并查集吧 一开始数组开太 ...
- BZOJ2594 [Wc2006]水管局长数据加强版 LCT kruskal
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2594 题意概括 N个点的图,M条带权边.(N<=100000,M<=1000000) ...
- [bzoj2594][Wc2006]水管局长数据加强版——lct+离线
Brief Description 您有一个无向带权图,您需要支持两种操作. 询问两个点之间的最大权最小路径. 删除一条边. Algorithm Design 我们首先提出一个猜想:最优路径一定在原图 ...
- BZOJ2594: [Wc2006]水管局长数据加强版
题解: 裸LCT+离线+二分+MST... 代码:(几乎摘抄自hzwer) #include<cstdio> #include<cstdlib> #include<cma ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 2917 Solved: 918[Submit][St ...
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...
- BZOJ2594 [Wc2006]水管局长数据加强版 【LCT维护最小生成树】
题目 SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一条从A至B的水管的 ...
- [BZOJ2594] [Wc2006]水管局长数据加强版(LCT + kruskal + 离线)
传送门 WC这个题真是丧心病狂啊,就是想学习一下怎么处理边权,给我来了这么一个破题! ORZ hzwer 临摹黄学长代码233 但还是复杂的一匹 理一下思路吧 题目大意:给定一个无向图,多次删除图中的 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 (LCT维护最小生成树)
离线做,把删边转化为加边,那么如果加边的两个点不连通,直接连就行了.如果联通就找他们之间的瓶颈边,判断一下当前边是否更优,如果更优就cut掉瓶颈边,加上当前边. 那怎么维护瓶颈边呢?把边也看做点,向两 ...
随机推荐
- linux命令 iperf-网络性能测试工具
博主推荐:更多网络测试相关命令关注 网络测试 收藏linux命令大全 iperf命令是一个网络性能测试工具.iperf可以测试TCP和UDP带宽质量.iperf可以测量最大TCP带宽,具有多种参数和 ...
- stark组件之删除页面内容搭建(八)
删除页面没有太多的内容和功能 def del_view(self, request,pk,*args,**kwargs): """ 处理删除表弟 :param reque ...
- Python操作Redis、Memcache
今天主要介绍如何通过python来对Redis和memcache进行操作,下面开始今天的内容: 一.Memcached操作 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web ...
- Apache Ambari 2.7.3.0 离线安装
1. 准备 (内存 3G 硬盘 40G) 0)设置ssh无密码 ssh-keygencat id_rsa.pub >> authorized_keyschmod 700 ~/.sshchm ...
- ..net 3.5新特性之用this关键字为类添加扩展方法
具体用法如下: public static class ClassHelper { //用this 声明将要吧这个方法附加到Student对象 public static bool CheckName ...
- CentOS下LVS DR模式负载均衡配置详解
一安装LVS准备: 1.准备4台Centos 6.2 x86_64 注:本实验关闭 SELinux和IPtables防火墙. 管理IP地址 角色 备注 192.168.1.101 LVS主调度器(Ma ...
- [luoguP1136] 迎接仪式(DP)
传送门 每个字母只有两种选择,变成另一个或者不变. 所以f[i][j][k]表示前i个字母有j个j变成z,有k个z变成j 只需要比较j==k时的答案就行 #include <cstdio> ...
- 【NOIP2016】蚯蚓(单调队列)
题意: 思路: 我们发现,对于任意两次切割i和j,i<j,在进行完第j次切割后,第i次切割的u/v部分一定大于等于第j次切割的u/v部分,第i次的1-u/v部分也一定大于等于第j次的1-u/v部 ...
- Linux下汇编语言学习笔记1 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- codevs——1275 有鱼的声音
1275 有鱼的声音 2012年CCC加拿大高中生信息学奥赛 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 查看运行结果 题目描述 Des ...