zoukankan      html  css  js  c++  java
  • [WC2006]水管局长

    X.[WC2006]水管局长

    或许我这题应该放到V.[NOI2014]魔法森林前面的QaQ?

    这题首先一眼看出翻转加边顺序。然后,动态维护最小生成森林,这样保证最小生成森林上的路径上的最大值就是原图中路径的最大值的可能的最小值。反正随便写写就行了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define lson t[x].ch[0]
    #define rson t[x].ch[1]
    int n,m,q;
    struct LCT{
    	int ch[2],fa,val,mx,rev;
    }t[1001000];
    int identify(int x){
    	if(t[t[x].fa].ch[0]==x)return 0;
    	if(t[t[x].fa].ch[1]==x)return 1;
    	return -1;
    }
    void pushup(int x){
    	t[x].mx=x;
    	if(lson&&t[t[lson].mx].val>t[t[x].mx].val)t[x].mx=t[lson].mx;
    	if(rson&&t[t[rson].mx].val>t[t[x].mx].val)t[x].mx=t[rson].mx;
    }
    void REV(int x){
    	t[x].rev^=1,swap(lson,rson);
    }
    void pushdown(int x){
    	if(!t[x].rev)return;
    	if(lson)REV(lson);
    	if(rson)REV(rson);
    	t[x].rev=false;
    }
    void rotate(int x){
    	int y=t[x].fa;
    	int z=t[y].fa;
    	int dirx=identify(x);
    	int diry=identify(y);
    	int b=t[x].ch[!dirx];
    	if(diry!=-1)t[z].ch[diry]=x;t[x].fa=z;
    	if(b)t[b].fa=y;t[y].ch[dirx]=b;
    	t[y].fa=x,t[x].ch[!dirx]=y;
    	pushup(y),pushup(x);
    }
    void pushall(int x){
    	if(identify(x)!=-1)pushall(t[x].fa);
    	pushdown(x);
    }
    void splay(int x){
    	pushall(x);
    	while(identify(x)!=-1){
    		int fa=t[x].fa;
    		if(identify(fa)==-1)rotate(x);
    		else if(identify(fa)==identify(x))rotate(fa),rotate(x);
    		else rotate(x),rotate(x);
    	}
    }
    void access(int x){
    	for(int y=0;x;x=t[y=x].fa)splay(x),rson=y,pushup(x);
    }
    void makeroot(int x){
    	access(x),splay(x),REV(x);
    }
    int findroot(int x){
    	access(x),splay(x);
    	pushdown(x);
    	while(lson)x=lson,pushdown(x);
    	splay(x);
    	return x;
    }
    void split(int x,int y){
    	makeroot(x),access(y),splay(y);
    }
    void link(int x,int y){
    	makeroot(x),t[x].fa=y;
    }
    void cut(int x,int y){
    	split(x,y),t[x].fa=t[y].ch[0]=0,pushup(y);
    }
    pair<int,int>p[100100];
    struct query{
    	int tp,x,y;
    }r[100100];
    bool des[100100];
    map<pair<int,int>,int>mp;
    void LINK(int id){
    	if(findroot(p[id].first)!=findroot(p[id].second))link(p[id].first,id+n),link(p[id].second,id+n);
    	else{
    		split(p[id].first,p[id].second);
    		int tmp=t[p[id].second].mx;
    		if(t[tmp].val<=t[id+n].val)return;
    		cut(tmp,p[tmp-n].first),cut(tmp,p[tmp-n].second);
    		link(p[id].first,id+n),link(p[id].second,id+n);
    	}
    }
    stack<int>S;
    int main(){
    	scanf("%d%d%d",&n,&m,&q);
    	for(int i=1;i<=m;i++){
    		scanf("%d%d%d",&p[i].first,&p[i].second,&t[i+n].val);
    		if(p[i].first>p[i].second)swap(p[i].first,p[i].second);
    		mp[p[i]]=i;
    	}
    	for(int i=1;i<=q;i++){
    		scanf("%d%d%d",&r[i].tp,&r[i].x,&r[i].y);
    		if(r[i].x>r[i].y)swap(r[i].x,r[i].y);
    		if(r[i].tp==2)des[mp[make_pair(r[i].x,r[i].y)]]=true;
    	}
    	for(int i=1;i<=m;i++)if(!des[i])LINK(i);
    	for(int i=q;i;i--)if(r[i].tp==2)LINK(mp[make_pair(r[i].x,r[i].y)]);else split(r[i].x,r[i].y),S.push(t[t[r[i].y].mx].val);
    	while(!S.empty())printf("%d\n",S.top()),S.pop();
    	return 0;
    } 
    

  • 相关阅读:
    Linux常见问题解决
    (转)CoreDNS:Kubernetes内部域名解析原理、弊端及优化方式
    (转)Go sync.WaitGroup的用法
    (转)5个维度对 Kubernetes 集群优化及压测方案
    使用 Alpine 作为基础镜像时可能会遇到的常见问题的解决方法
    提前预防K8s集群资源不足的处理方式配置
    docker runc升级
    Nginx常见问题解决
    DNS泛域名解析应用(nip.io)
    使用Velero备份Kubernetes集群
  • 原文地址:https://www.cnblogs.com/Troverld/p/14601991.html
Copyright © 2011-2022 走看看