• 题解 P2195 【HXY造公园】


    天哪这道题竟然只有一篇题解!


    emm,首先读题看完两个操作就已经有很明确的思路了,显然是并查集+树的直径 一波解决。

    并查集不多说了,如果不了解的可以看这里.

    树的直径的思路很朴实,就是两边DFS(BFS也OK)。具体先随便找一个节点,然后搜一遍,找到最远的,然后再搜一遍,这样合在一起就一定是最长的了。

    不过呢这道题还是注意一下求直径的公式,具体如下:

    $D_new=max(D_u,D_v,[D_u/2]+[D_v/2]+1)$

    那个方括号指的是取整(没找到在哪里打出来)。

    en除此之外好像没什么好说的。。。

    AC代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 using namespace std;
     6 
     7 const int maxn=300300;
     8 
     9 int n,m,q,max_i,max_v;
    10 int f[maxn],len[maxn],sz[maxn];
    11 bool used[maxn];
    12 vector<int>g[maxn];
    13 
    14 void dfs(int val,int depth,int pos){
    15     if(depth>max_i){
    16         max_i=depth;
    17         max_v=val;
    18     }
    19     for(int i=0;i<g[val].size();i++){
    20         if(g[val][i]!=pos)dfs(g[val][i],depth+1,val);
    21     }
    22 }
    23 
    24 int calc(int val){
    25     max_i=-1;
    26     dfs(val,0,-1);
    27     max_i=-1;
    28     dfs(max_v,0,-1);
    29     return max_i;
    30 }
    31 
    32 int find(int x){
    33     if(x==f[x])return x;
    34     return f[x]=find(f[x]);
    35 }
    36 
    37 void merge(int x,int y){
    38     x=find(x),y=find(y);
    39     if(sz[x]>sz[y])swap(x,y);
    40     sz[y]+=sz[x];
    41     f[x]=y;
    42 }
    43 
    44 int radius(int x){
    45     return (len[x]+1)/2;
    46 }
    47 
    48 void merge2(int x,int y){
    49     x=find(x),y=find(y);
    50     if(x==y)return;
    51     if(sz[x]>sz[y])swap(x,y);
    52     sz[y]+=sz[x];
    53     f[x]=y;
    54     len[y]=max(max(radius(x)+radius(y)+1,len[x]),len[y]);
    55 }
    56 
    57 int main() {
    58     scanf("%d%d%d",&n,&m,&q);
    59     for(int i=1;i<=n;i++){
    60         f[i]=i;
    61         sz[i]=i;
    62         len[i]=0;
    63     }
    64     for(int i=1;i<=m;i++){
    65         int x,y;
    66         scanf("%d%d",&x,&y);
    67         g[x].push_back(y);
    68         g[y].push_back(x);
    69         merge(x,y);
    70     }
    71     for(int i=1;i<=n;i++){
    72         int p=find(i);
    73         if(!used[p]){
    74             used[p]=1;
    75             len[p]=calc(i);
    76         }
    77     }
    78     while(q--){
    79         int t,x,y;
    80         scanf("%d",&t);
    81         if(t==1){
    82             scanf("%d",&x);
    83             printf("%d
    ",len[find(x)]);
    84         }else{
    85             scanf("%d%d",&x,&y);
    86             merge2(x,y);
    87         }
    88     }
    89 }
  • 相关阅读:
    [PHP] laravel框架注意bootstrap/cache
    [git] git拉取远程分支代码
    Prometheus监控系统(4)pushgateway及自定义脚本
    k8s 学习
    pxc /Galera Cluster详解
    Percona Monitoring and Management
    etcd获取所有key
    kubernetes Pod驱逐迁移drain用法
    kubernetes etcd数据管理
    办公环境下k8s网络互通方案
  • 原文地址:https://www.cnblogs.com/ilverene/p/9819088.html
Copyright © 2020-2023  润新知