• CF734E Anton and Tree(并查集+树的直径)


    题目链接:https://www.luogu.com.cn/problem/CF734E

    首先用并查集将题目中原先的相邻的颜色相同的点进行缩点,用并查集来完成。然后考虑如何改变是最优的。将缩点后的点建树,找到树的直径,不断改变直径的中点及其相邻颜色块的颜色,会让整个树在floor(len+1)次完成改变全部颜色(len为直径长度)。其他不是直径的枝叶会在改变直径时直接改变掉。

    AC代码:

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<queue>
     7 using namespace std;
     8 const int N=200005;
     9 int n,tot,maxd;
    10 queue<int> q;
    11 int x[N],y[N],c[N],head[N],f[N],vis[N],d[N];
    12 struct node{
    13     int to,next;
    14 }edge[N<<1];
    15 void init(){
    16     memset(head,-1,sizeof(head));
    17 }
    18 int find(int x){
    19     if(f[x]!=x) f[x]=find(f[x]);
    20     return f[x];
    21 }
    22 void add(int u,int v){
    23     edge[tot].next=head[u];
    24     edge[tot].to=v;
    25     head[u]=tot++;
    26 }
    27 int BFS(int s){
    28     int pos;
    29     maxd=0;
    30     memset(d,0,sizeof(d));
    31     memset(vis,0,sizeof(vis));
    32     while(!q.empty()) q.pop();
    33     q.push(s); vis[s]=1;
    34     while(!q.empty()){
    35         int u=q.front(); q.pop();
    36         for(int i=head[u];i!=-1;i=edge[i].next){
    37             int v=edge[i].to;
    38             if(vis[v]) continue;
    39             vis[v]=1;
    40             d[v]=d[u]+1;
    41             q.push(v);
    42             if(maxd<d[v]){
    43                 maxd=d[v];
    44                 pos=v;
    45             }
    46         }
    47     }
    48     return pos;
    49 }
    50 int main(){
    51     init();
    52     scanf("%d",&n);
    53     for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    54     for(int i=1;i<=n;i++) f[i]=i;
    55     for(int i=1;i<n;i++){
    56         scanf("%d%d",&x[i],&y[i]);
    57         int r1=find(x[i]),r2=find(y[i]);
    58         if(c[r1]==c[r2]) f[r1]=r2;
    59     }
    60     for(int i=1;i<=n;i++) f[i]=find(f[i]);//缩点
    61     for(int i=1;i<n;i++) if(f[x[i]]!=f[y[i]]) add(f[x[i]],f[y[i]]),add(f[y[i]],f[x[i]]);
    62     int l=BFS(f[x[1]]);
    63     BFS(l);
    64     int ans=floor((maxd+1)/2);
    65     printf("%d",ans);
    66     return 0;
    67 }
    AC代码
  • 相关阅读:
    唯品会面经
    动态代理两种实现方式
    腾讯运营开发面经
    MySQL一些中重要命令
    金山wps面经
    三七互娱面经
    排序算法之快速排序(Quicksort)解析
    全排列算法分析(原创方法/一般方法/字典序法)
    WinForm如何去掉右边和下边的白边
    Java异常处理机制的秘密
  • 原文地址:https://www.cnblogs.com/New-ljx/p/13472172.html
Copyright © 2020-2023  润新知