题解 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 }
原文地址:https://www.cnblogs.com/ilverene/p/9819088.html