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

    原题链接

    前言

    搞不懂为什么要写LCT,搞不懂为什么要加强数据。像这道题是用父亲表示法来做的。虽然复杂度不是log,但是现在下面这份代码却是无论从空间,还是代码量,还是时间都是优秀不止一点。 而且这样还能出在noip这样的考试


    sol

    一个烂大街的套路就是离线搞。这也是这道题的唯一难点。估计大佬们都已经讲透了。

    但是为了照顾我这样的不会LCT的蒟蒻,这里有一个更好的办法,那就是直接用fa[]数组来维系这棵树。比如说,要把u,v相连,首先把u向上用fa数组跑,然后一路将fa数组反向。

    然后就可以直接赋值fa[u]=v。

    但是写的时候还是心虚,所以写的十分小心,应该把常数弄到最小了。代码一定不能写丑

    code

    #include<bits/stdc++.h>
    using namespace std;
    const int _=1e6+22;
    int fa[1001],g[1001][1001],n,m,Q,anss[_/10],mm,par[1001],sign[1001],cnt;
    int rec[1001];
    struct Edge{
        int u,v,w;
    }e[_],e1[_];
    struct MO{
        int u,v,k;
    }mo[_];
    inline char gc(){
        static char buf[1<<6],*p1=buf,*p2=buf;
        return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,1<<6,stdin),p1==p2)?EOF:*p1++;
    }
    template <class T>
    inline void read(T&data){
        data=0;
        register char ch=0;
        while(ch<'0'||ch>'9')ch=gc();
        while(ch<='9'&&ch>='0'){
            data=(data<<1)+(data<<3)+(ch^48);
            ch=gc();
        }
    }
    template <class R>
    inline void write(R data){
        if(data>9)write(data/10);
        putchar('0'+data%10);
    }
    bool cmp(register Edge a,register Edge b){return a.w<b.w;}
    int fi(register int x){return x==par[x]?x:par[x]=fi(par[x]);}
    int main(){
        read(n),read(m),read(Q);
        register int i,u,v,fu,fv,ff,qq,now,LCA,ans,ANS;
        for(i=1;i<=m;++i){
            register Edge & fff=e1[i];
            read(fff.u),read(fff.v),read(fff.w);
        }
        for(i=1;i<=Q;++i){
            register MO& IOI=mo[i]; 
            read(IOI.k),read(IOI.u),read(IOI.v);
            if(IOI.k==2)g[IOI.v][IOI.u]=1,g[IOI.u][IOI.v]=1;
        }
        for(i=1;i<=m;++i){
            register int &IOI=g[e1[i].u][e1[i].v];
            if(!IOI)e[++mm]=e1[i];
            IOI=g[e1[i].v][e1[i].u]=e1[i].w;
        }
        sort(e+1,e+mm+1,cmp);
        for(i=1;i<=n;++i)par[i]=i;
        for(i=1;i<=mm;++i){
            u=e[i].u,v=e[i].v,fu=fi(u),fv=fi(v);
            if(fu==fv)continue;
            par[fu]=fv,ff=fa[u],qq=u;
            while(ff)
                swap(fa[ff],qq),swap(ff,qq);            
            fa[u]=v;
        }
        for(i=Q;i;--i){
            u = mo[i].u,v=mo[i].v,now=u,rec[now]=0;
            while(now){sign[now]=i,rec[fa[now]]=max(rec[now],g[now][fa[now]]),now=fa[now];}
            LCA=v,ans=0,ANS=0;
            while(LCA&&sign[LCA]!=i){ans=max(ans,g[LCA][fa[LCA]]),LCA=fa[LCA];}
            ANS=max(ans,rec[LCA]);
            if(mo[i].k==1){anss[++cnt]=ANS;}
            else {
                if(ANS<=g[u][v])continue;
                if(ans>rec[LCA])swap(u,v);
                ff=fa[u],qq=u;
                while(g[qq][ff]!=ANS){
                    swap(fa[ff],qq),swap(ff,qq);
                }
                fa[u]=v;
            }
    
        }
        for(i=cnt;i;--i)write(anss[i]),puts("");
        return 0;   
    }
  • 相关阅读:
    C#开发: 通信篇-串口调试助手
    C#开发: 准备工作-C# 新建工程
    C#开发: 准备工作-Visual Studio 安装
    ESP8266 SDK开发: 外设篇-串口
    ESP8266 SDK开发: 外设篇-定时器,延时
    ESP8266 SDK开发: 外设篇-GPIO中断检测
    【java编程】加载Resources配置文件的方法
    【java高级编程】jdk自带事件模型编程接口
    【mybatis源码学习】mybtias知识点
    【java编程-Javassist】秒懂Java动态编程(Javassist研究)
  • 原文地址:https://www.cnblogs.com/zzrblogs/p/10462013.html
Copyright © 2011-2022 走看看