ツリー径CF455C文明

問題の説明

LG-CF455C


問題の解決策

まず、被験者が与えられ\(M \)エッジ、この\(N- \)点、\(M \)使用しながら、森林、各ツリーの乱径からなるエッジ互いに素なセットツリーメンテナンス接続。

2つのツリーをマージした場合を考えてみましょう:に元を表す2つのツリーましょう\(U、Vを\) このツリーは、次の3つのソースの直径を有しています。

  • \(U \)木の直径

  • \(V \)木の直径

  • スルー(U、V \)\パス合流エッジ

\(U、V \)我々は唯一の第三のケースを最小限に抑えるために検討する必要があるので、2つのツリーの直径は、知られています。

提供ツリー\(U、V \)点がマージされる(rt_u、Rt_v \)\、第三の場合、この時間は、(\ FRAC {maxdis_ {rt_u \ }} {2} + \ FRAC {maxdis_ { rt_v}} {2} +1 \ )

明らかに、2最小限にするために、\(maxdis \)を、二つの点は、元の2つのツリーの直径の中点を選択しなければなりません。


\(\ mathrm {コード} \)

#include<bits/stdc++.h>
using namespace std;

template <typename Tp>
void read(Tp &x){
    x=0;char ch=1;int fh;
    while(ch!='-'&&(ch>'9'||ch<'0')) ch=getchar();
    if(ch=='-') ch=getchar(),fh=-1;
    else fh=1;
    while(ch>='0'&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    x*=fh;
}

const int maxn=300007;
const int maxm=600007;

int n,m,T;
vector<int> G[maxn];
int fa[maxn];

int bel[maxn],cnt;

void add(int x,int y){
    G[x].push_back(y);
}

int find(int x){
    return fa[x]==x?x:fa[x]=find(fa[x]);
}

int dep[maxn],ans[maxn];

int pos,lst;

void merge(int x,int y){
    if(find(x)!=find(y)) fa[fa[x]]=fa[y];
}

void dfs(int x,int col,int dis){
    if(bel[x]==col) return;
    if(dis>=lst) lst=dis,pos=x;
    bel[x]=col;
    for(int i=0;i<G[x].size();i++){
        int y=G[x][i];
        merge(x,y);
        dfs(y,col,dis+1);
    }
}

void Getmax(){
    int mx=-1;
    for(int i=1;i<=n;i++){
        if(dep[i]>mx) mx=dep[i],pos=i;
    }
}

void cz1(){
    int x;read(x);
    printf("%d\n",ans[find(x)]);
}

void cz2(){
    int x,y;read(x);read(y);
    int xx=find(x),yy=find(y);
    if(xx==yy) return;
    fa[xx]=yy;
    ans[yy]=max(ans[xx],max(ans[yy],(ans[xx]+1)/2+(ans[yy]+1)/2+1));
}

void preprocess(){
    for(int i=1;i<=n;i++) fa[i]=i;
}

int main(){
    read(n);read(m);read(T);
    
    preprocess();
    
    for(int i=1,x,y;i<=m;i++){
        read(x);read(y);
        add(x,y);add(y,x);
    }
    
    for(int i=1;i<=n;i++){
        if(bel[i]) continue;
        lst=0,pos=i;
        dfs(i,i,0);
        lst=0;
        dfs(pos,pos,0);
        ans[find(i)]=lst;
    }
    
    int op;
    while(T--){
        read(op);
        if(op==1) cz1();
        else cz2();
    }
    
    return 0;
}

おすすめ

転載: www.cnblogs.com/liubainian/p/11815905.html