zoukankan      html  css  js  c++  java
  • 【BZOJ2594】【WC2010】—水管局长数据加强版(LCT维护最小生成树)

    传送门

    水题,发现就是维护一个最小生成树

    由于卡时间 ,就不直接用LCTLCT连断边
    先做一次KruscalKruscal

    化边为点就可以了

    不要用mapmap,似乎要被卡空间,每次二分判断

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<22|1;
    inline char gc(){
    	static char ibuf[RLEN],*ib,*ob;
    	(ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
    	return (ob==ib)?EOF:*ib++;
    }
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    const int N=1500005;
    struct E{
    	int u,v,w,pos;bool des;
    }e[N];
    inline bool comp(const E&a,const E&b){
    	return a.w<b.w;
    }
    inline bool cmp(const E&a,const E&b){
    	return a.u==b.u?a.v<b.v:a.u<b.u;
    }
    inline bool cp(const E&a,const E&b){
    	return a.pos<b.pos;
    }
    struct oper{
    	int op,u,v,pos,ans;
    }p[N];
    int val[N],f[N],n,m,q,cnt,tot;
    namespace LCT{
    	int mx[N],son[N][2],fa[N],que[N];bool rev[N];
    	#define lc(u) son[u][0]
    	#define rc(u) son[u][1]
    	inline bool isrt(int u){
    		if(!fa[u])return 1;
    		return lc(fa[u])!=u&&rc(fa[u])!=u;
    	}
    	inline bool isrc(int u){
    		return rc(fa[u])==u;
    	}
    	inline void pushup(int u){
    		mx[u]=u;
    		if(val[mx[u]]<val[mx[lc(u)]])mx[u]=mx[lc(u)];
    		if(val[mx[u]]<val[mx[rc(u)]])mx[u]=mx[rc(u)];
    	}
    	inline void pushdown(int u){
    		if(!rev[u])return;
    		if(lc(u))rev[lc(u)]^=1;
    		if(rc(u))rev[rc(u)]^=1;
    		swap(lc(u),rc(u)),rev[u]=0;
    	}
    	inline void rotate(int v){
    		int u=fa[v],z=fa[u];
    		int t=(rc(u)==v);
    		if(!isrt(u))son[z][rc(z)==u]=v;
    		fa[v]=z;
    		son[u][t]=son[v][t^1],fa[son[v][t^1]]=u;
    		son[v][t^1]=u,fa[u]=v;
    		pushup(u),pushup(v);
    	}
    	inline void splay(int u){
    		que[que[0]=1]=u;
    		for(int v=u;!isrt(v);v=fa[v])que[++que[0]]=fa[v];
    		for(int i=que[0];i;i--)pushdown(que[i]);
    		while(!isrt(u)){
    			if(!isrt(fa[u]))
    				isrc(fa[u])==isrc(u)?rotate(fa[u]):rotate(u);
    			rotate(u);
    		}
    		pushup(u);
    	}
    	inline void access(int u){
    		for(int v=0;u;v=u,u=fa[u]){
    			splay(u),rc(u)=v;if(v)fa[v]=u;pushup(u);
    		}
    	}
    	inline void makert(int u){
    		access(u),splay(u),rev[u]^=1;
    	}
    	inline void link(int u,int v){
    		makert(u),fa[u]=v;
    	}
    	inline void cut(int u,int v){
    		makert(u),access(v),splay(v),lc(v)=fa[u]=0;
    	}
    	inline int query(int u,int v){
    		makert(u),access(v),splay(v);return mx[v];
    	}
    }
    using namespace LCT;
    char u;
    int find(int x){
    	return f[x]==x?x:f[x]=find(f[x]);
    }
    inline int find(int u,int v){
    	int l=1,r=m;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(e[mid].u<u||(e[mid].u==u&&e[mid].v<v))l=mid+1;
    		else if(e[mid].u==u&&e[mid].v==v)return mid;
    		else r=mid-1;
    	}
    }a
    int main(){
    	n=read(),m=read(),q=read();
    	for(int i=1;i<=n;i++)f[i]=i;
    	for(int i=1;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+1,e+m+1,comp);
    	for(int i=1;i<=m;i++){
    		e[i].pos=i;
    		val[n+i]=e[i].w;
    		mx[n+i]=n+i;
    	}
    	sort(e+1,e+m+1,cmp);
    	for(int i=1;i<=q;i++){
    		p[i].op=read(),p[i].u=read(),p[i].v=read();
    		if(p[i].op==2){
    			if(p[i].u>p[i].v)swap(p[i].u,p[i].v);
    			int t=find(p[i].u,p[i].v);
    			e[t].des=1,p[i].pos=e[t].pos;
    		}
    	}
    	sort(e+1,e+m+1,cp);
    	for(int i=1;i<=m;i++){
    		if(e[i].des)continue;
    		int f1=find(e[i].u),f2=find(e[i].v);
    		if(f1!=f2){
    			f[f1]=f2;
    			link(e[i].u,i+n),link(e[i].v,i+n);
    		}
    	}
    	for(int i=q;i;i--){
    		if(p[i].op==1)p[i].ans=val[query(p[i].u,p[i].v)];
    		else{
    			int u=p[i].u,v=p[i].v,k=p[i].pos;
    			int t=query(u,v);
    			if(e[k].w<val[t]){
    				cut(e[t-n].u,t),cut(e[t-n].v,t);
    				link(u,k+n),link(v,k+n);
    			}
    		}
    	}
    	for(int i=1;i<=q;i++)if(p[i].op==1)cout<<p[i].ans<<'
    ';
    }
    
  • 相关阅读:
    C#第十六节课
    Hadoop系列(三):hadoop基本测试
    Hadoop系列(二):Hadoop单节点部署
    Hadoop系列(一):Hadoop集群搭建
    Stars project
    Tornado实现多进程/多线程的HTTP服务
    python paramiko模块
    爬虫代理
    tornado之用户验证装饰器
    tornado自定义session
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145550.html
Copyright © 2011-2022 走看看