BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]
2594: [Wc2006]水管局长数据加强版
Time Limit: 25 Sec Memory Limit: 128 MB
Submit: 2917 Solved: 918
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 2 2
2 3 3
3 4 2
1 4 2
1 1 4
2 1 4
1 1 4
Sample Output
3
【原题数据范围】
N ≤ 1000
M ≤ 100000
Q ≤ 100000
测试数据中宣布报废的水管不超过5000条;且任何时候我们考虑的水管网络都是连通的,即从任一结点A必有至少一条水管路径通往任一结点B。
【加强版数据范围】
N ≤ 100000
M ≤ 1000000
Q ≤ 100000
任何时候我们考虑的水管网络都是连通的,即从任一结点A必有至少一条水管路径通往任一结点B。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pa t[x].fa
#define lc t[x].ch[0]
#define rc t[x].ch[1]
const int N=15e5+,NN=1e5+;
typedef long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,Q; struct node{
int ch[],fa,rev,mx,mxp,w;
}t[N];
inline int wh(int x){return t[pa].ch[]==x;}
inline int isRoot(int x){return t[pa].ch[]!=x&&t[pa].ch[]!=x;}
inline void update(int x){
t[x].mx=t[x].w;t[x].mxp=x;
if(t[lc].mx>t[x].mx) t[x].mx=t[lc].mx,t[x].mxp=t[lc].mxp;
if(t[rc].mx>t[x].mx) t[x].mx=t[rc].mx,t[x].mxp=t[rc].mxp;
}
inline void rever(int x){
t[x].rev^=;
swap(lc,rc);
}
inline void pushDown(int x){
if(t[x].rev){
rever(lc);
rever(rc);
t[x].rev=;
}
}
inline void rotate(int x){
int f=t[x].fa,g=t[f].fa,c=wh(x);
if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g;
t[f].ch[c]=t[x].ch[c^];t[t[f].ch[c]].fa=f;
t[x].ch[c^]=f;t[f].fa=x;
update(f);update(x);
}
int st[N],top;
inline void splay(int x){
top=;st[++top]=x;
for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa;
for(int i=top;i>=;i--) pushDown(st[i]); for(;!isRoot(x);rotate(x))
if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x);
} inline void Access(int x){
for(int y=;x;y=x,x=pa){
splay(x);
rc=y;
update(x);
}
}
inline void MakeR(int x){
Access(x);splay(x);
rever(x);
}
inline int FindR(int x){
Access(x);splay(x);
while(lc) x=lc;
return x;
}
inline void Link(int x,int y){
MakeR(x);
t[x].fa=y;
}
inline void Cut(int x,int y){
MakeR(x);Access(y);splay(y);
t[y].ch[]=t[x].fa=;
update(y);//!!!
}
inline void Split(int x,int y){
MakeR(x);Access(y);splay(y);
} int del[N];
struct edge{
int u,v,w,id;
bool operator <(const edge &e)const{return w<e.w;}
}e[N];
inline bool cmpuv(edge a,edge b){
return a.u<b.u||(a.u==b.u&&a.v<b.v);
}
inline bool cmpid(edge a,edge b){
return a.id<b.id;
}
int bs(int u,int v){
int l=,r=m;
while(l<=r){
int mid=(l+r)>>;
if(e[mid].u==u&&e[mid].v==v) return mid;
else if(e[mid].u<u||(e[mid].u==u&&e[mid].v<v)) l=mid+;
else r=mid-;
}
return ;
}
struct ques{
int op,x,y,del,ans;
}q[NN];
int fa[N];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void solve(){
for(int i=;i<=n;i++) fa[i]=i;
sort(e+,e++m,cmpid);
int tot=;
for(int i=;i<=m;i++) if(!del[i]){
int x=find(e[i].u),y=find(e[i].v);//printf("hieid %d %d %d %d\n",i,e[i].id,x,y);
if(x!=y){
Link(e[i].u,i+n);Link(e[i].v,i+n);
fa[x]=y;
tot++;
if(tot==n-) break;
}
} for(int i=Q;i>=;i--){
int x=q[i].x,y=q[i].y;
if(q[i].op==){
Split(x,y);
q[i].ans=t[y].mx;//printf("ans %d %d\n",i,t[y].mx);
}else{
int k=q[i].del;//try to add e[k]
Split(x,y);
if(e[k].w<t[y].mx){
int p=t[y].mxp;//printf("replace %d %d\n",p-n,k);
Cut(e[p-n].u,p);Cut(e[p-n].v,p);
Link(x,k+n);Link(y,k+n);
}
}
}
for(int i=;i<=Q;i++) if(q[i].op==) printf("%d\n",q[i].ans);
}
int main(){
//freopen("in.txt","r",stdin);
n=read();m=read();Q=read();
for(int i=;i<=m;i++){
e[i].u=read(),e[i].v=read(),e[i].w=read();
if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
}
sort(e+,e++m);
for(int i=;i<=m;i++){//printf("e %d %d %d %d\n",i,e[i].u,e[i].v,e[i].w);
e[i].id=i;
t[n+i].w=t[n+i].mx=e[i].w;
t[n+i].mxp=n+i;
}
sort(e+,e++m,cmpuv);
for(int i=;i<=Q;i++){
q[i].op=read(),q[i].x=read(),q[i].y=read();
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
if(q[i].op==){
int k=e[bs(q[i].x,q[i].y)].id;
del[k]=;//printf("del %d\n",k);
q[i].del=k;
}
}
solve();
}
LCT直接保存最大编号也可以
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define pa t[x].fa
#define lc t[x].ch[0]
#define rc t[x].ch[1]
const int N=15e5+,NN=1e5+;
typedef long long ll;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,m,Q; struct node{
int ch[],fa,rev,mxp;
}t[N];
int val[N];
inline int wh(int x){return t[pa].ch[]==x;}
inline int isRoot(int x){return t[pa].ch[]!=x&&t[pa].ch[]!=x;}
inline void update(int x){
t[x].mxp=x;
if(val[t[lc].mxp]>val[t[x].mxp]) t[x].mxp=t[lc].mxp;
if(val[t[rc].mxp]>val[t[x].mxp]) t[x].mxp=t[rc].mxp;
}
inline void rever(int x){
t[x].rev^=;
swap(lc,rc);
}
inline void pushDown(int x){
if(t[x].rev){
rever(lc);
rever(rc);
t[x].rev=;
}
}
inline void rotate(int x){
int f=t[x].fa,g=t[f].fa,c=wh(x);
if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g;
t[f].ch[c]=t[x].ch[c^];t[t[f].ch[c]].fa=f;
t[x].ch[c^]=f;t[f].fa=x;
update(f);update(x);
}
int st[N],top;
inline void splay(int x){
top=;st[++top]=x;
for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa;
for(int i=top;i>=;i--) pushDown(st[i]); for(;!isRoot(x);rotate(x))
if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x);
} inline void Access(int x){
for(int y=;x;y=x,x=pa){
splay(x);
rc=y;
update(x);
}
}
inline void MakeR(int x){
Access(x);splay(x);
rever(x);
}
inline int FindR(int x){
Access(x);splay(x);
while(lc) x=lc;
return x;
}
inline void Link(int x,int y){
MakeR(x);
t[x].fa=y;
}
inline void Cut(int x,int y){
MakeR(x);Access(y);splay(y);
t[y].ch[]=t[x].fa=;
update(y);//!!!
}
inline void Split(int x,int y){
MakeR(x);Access(y);splay(y);
}
inline int Que(int x,int y){
MakeR(x);Access(y);splay(y);
return t[y].mxp;
} int del[N];
struct edge{
int u,v,w,id;
bool operator <(const edge &e)const{return w<e.w;}
}e[N];
inline bool cmpuv(edge a,edge b){
return a.u<b.u||(a.u==b.u&&a.v<b.v);
}
inline bool cmpid(edge a,edge b){
return a.id<b.id;
}
int bs(int u,int v){
int l=,r=m;
while(l<=r){
int mid=(l+r)>>;
if(e[mid].u==u&&e[mid].v==v) return mid;
else if(e[mid].u<u||(e[mid].u==u&&e[mid].v<v)) l=mid+;
else r=mid-;
}
return ;
}
struct ques{
int op,x,y,del,ans;
}q[NN];
int fa[N];
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void solve(){
for(int i=;i<=n;i++) fa[i]=i;
sort(e+,e++m,cmpid);
int tot=;
for(int i=;i<=m;i++) if(!del[i]){
int x=find(e[i].u),y=find(e[i].v);//printf("hieid %d %d %d %d\n",i,e[i].id,x,y);
if(x!=y){
Link(e[i].u,i+n);Link(e[i].v,i+n);
fa[x]=y;
tot++;
if(tot==n-) break;
}
} for(int i=Q;i>=;i--){
int x=q[i].x,y=q[i].y;
if(q[i].op==){
int p=Que(x,y);
q[i].ans=val[p];//printf("ans %d %d\n",i,t[y].mx);
}else{
int k=q[i].del;//try to add e[k]
int p=Que(x,y);
if(e[k].w<val[p]){
Cut(e[p-n].u,p);Cut(e[p-n].v,p);
Link(x,k+n);Link(y,k+n);
}
}
}
for(int i=;i<=Q;i++) if(q[i].op==) printf("%d\n",q[i].ans);
}
int main(){
//freopen("in.txt","r",stdin);
n=read();m=read();Q=read();
for(int i=;i<=m;i++){
e[i].u=read(),e[i].v=read(),e[i].w=read();
if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
}
sort(e+,e++m);
for(int i=;i<=m;i++){//printf("e %d %d %d %d\n",i,e[i].u,e[i].v,e[i].w);
e[i].id=i;
val[n+i]=e[i].w;
t[n+i].mxp=n+i;
}
sort(e+,e++m,cmpuv);
for(int i=;i<=Q;i++){
q[i].op=read(),q[i].x=read(),q[i].y=read();
if(q[i].x>q[i].y) swap(q[i].x,q[i].y);
if(q[i].op==){
int k=e[bs(q[i].x,q[i].y)].id;
del[k]=;//printf("del %d\n",k);
q[i].del=k;
}
}
solve();
}
BZOJ 2594: [Wc2006]水管局长数据加强版 [LCT kruskal]的更多相关文章
- BZOJ 2594: [Wc2006]水管局长数据加强版( LCT )
离线然后就是维护加边的动态MST, Link cut tree秒掉..不过我写+调了好久...时间复杂度O(NlogN + MlogM) ------------------------------- ...
- BZOJ 2594: [Wc2006]水管局长数据加强版(kruskal + LCT)
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- BZOJ 2594: [Wc2006]水管局长数据加强版 (LCT维护最小生成树)
离线做,把删边转化为加边,那么如果加边的两个点不连通,直接连就行了.如果联通就找他们之间的瓶颈边,判断一下当前边是否更优,如果更优就cut掉瓶颈边,加上当前边. 那怎么维护瓶颈边呢?把边也看做点,向两 ...
- bzoj 2594: [Wc2006]水管局长数据加强版 动态树
2594: [Wc2006]水管局长数据加强版 Time Limit: 25 Sec Memory Limit: 128 MBSubmit: 934 Solved: 291[Submit][Sta ...
- [BZOJ 2594] [Wc2006]水管局长数据加强版 【LCT】
题目链接:BZOJ - 2594 题目分析 这道题如果没有删边的操作,那么就是 NOIP2013 货车运输,求两点之间的一条路径,使得边权最大的边的边权尽量小. 那么,这条路径就是最小生成树上这两点之 ...
- 【刷题】BZOJ 2594 [Wc2006]水管局长数据加强版
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- bzoj 2594: [Wc2006]水管局长数据加强版
Description SC省MY市有着庞大的地下水管网络,嘟嘟是MY市的水管局长(就是管水管的啦),嘟嘟作为水管局长的工作就是:每天供水公司可能要将一定量的水从x处送往y处,嘟嘟需要为供水公司找到一 ...
- bzoj 2594 [Wc2006]水管局长数据加强版(LCT+最小生成树)
[深坑勿入] [给个链接] http://blog.csdn.net/popoqqq/article/details/41348549 #include<cstdio> #include& ...
- BZOJ2594 [Wc2006]水管局长数据加强版 LCT kruskal
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2594 题意概括 N个点的图,M条带权边.(N<=100000,M<=1000000) ...
随机推荐
- .NET MongoDB Driver 2.2使用示例
说明:mongoDBService是对各种常用操作的封装 public class MongoDBService { #region 变量 /// <summary> /// 缓存 /// ...
- javascript如何处理多级的实时监听
今日工作中遇到需求,要求js代码对表单中的input内容进行实时监听,当input中的值改变时触发一些事件. 按照常规思维,代码很快写完了. $(function () { $("#inpu ...
- ASP.NET没有魔法——ASP.NET OAuth、jwt、OpenID Connect
上一篇文章介绍了OAuth2.0以及如何使用.Net来实现基于OAuth的身份验证,本文是对上一篇文章的补充,主要是介绍OAuth与Jwt以及OpenID Connect之间的关系与区别. 本文主要内 ...
- 再起航,我的学习笔记之JavaScript设计模式29(节流模式)
节流模式 概念介绍 节流模式(Throttler): 对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能. 优化滚动事件 有的时候我们再为滚动条添加动画的时候,会发现滚动条不停的 ...
- [国嵌笔记][019][Eclipse集成开发环境]
Eclipse集成开发环境的作用 可以编译程序,也可以对程序进行在线调试 集成开发环境 1.JLink连接开发板的JTAG 2.JLink连接PC的USB 3.eclipse软件 4.gdb serv ...
- HtmlHelper总结
HTML helper是在视图页面上操作HTML元素时可以调用的方法,还包括URL helper和AJAX helper.这些帮助方法都为了使得操作HTML更加容易.分为两类:a.编辑和输入帮助类b. ...
- 我在vs文本编辑中常用的快捷键----常更新
1. Ctrl+向上键----文本向上滚动 Ctrl+向下键----文本向下滚动 Ctrl+Enter-----向下增加一行 Ctrl+Shift+Enter-------向上增加一行 2. 避 ...
- [基础常识]申请免费SSL证书 - 阿里云云盾证书 - Digicert+Symantec 免费型DV SSL
https://bbs.aliyun.com/read/573933.html?spm=5176.10695662.1996646101.searchclickresult.72be06dct9Qvw ...
- PHP批量去除bom头代码的小工具
在 aitecms 群里有网友抱怨了好几天说本地的验证码一直无法显示,后来听说解决了,问其如何解决的,说是去除了文件 bom 就好了.后来百度到一篇文章也说 dedecms 的验证码不能显示,某次解决 ...
- Red Hat
同义词 REDHAT一般指Red Hat Red Hat(红帽)公司(NYSE:RHT)是一家开源解决方案供应商,也是标准普尔500指数成员.总部位于美国北卡罗来纳州的罗利市,截止2015年3月3日, ...