luogu P2195 HXY造公园

time cost:65min

这题……顿时让我对直径这个东西产生了深深地畏惧……
样例输出的直径全是0但是就应该是0……D了好久……
这道题操作1就是预处理所有直径就行
操作2比较恶心
将两个点连边的时候我们给他归进一个并查集
然后每次连点的时候求出每个并查集中的最大直径
每次加一对点连新边的时候用来更新的一定是之前最大值的/2上取整
求直径的时候找两遍就行

Code:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define itn int
 6 #define ms(a,b) memset(a,b,sizeof a)
 7 #define rep(i,a,n) for(int i = a;i <= n;i++)
 8 #define per(i,n,a) for(int i = n;i >= a;i--)
 9 #define inf 2147483647
10 using namespace std;
11 typedef long long ll;
12 ll read() {
13     ll as = 0,fu = 1;
14     char c = getchar();
15     while(c < '0' || c > '9') {
16         if(c == '-') fu = -1;
17         c = getchar();
18     }
19     while(c >= '0' && c <= '9') {
20         as = as * 10 + c - '0';
21         c = getchar();
22     }
23     return as * fu;
24 }
25 //head
26 const int N = 300006;
27 
28 int n,m,T;
29 int head[N],nxt[N<<1],mo[N<<1],cnt;
30 void _add(int x,int y) {
31     mo[++cnt] = y;
32     nxt[cnt] = head[x];
33     head[x] = cnt;
34 }
35 void add(int x,int y) {if(x^y)_add(x,y),_add(y,x);}
36 int pa[N];
37 int gpa(int x) {
38     if(x == pa[x]) return x;
39     return pa[x] = gpa(pa[x]);
40 }
41 
42 int dim[N];
43 void Merge(int x,int y) {
44     int fx = gpa(x),fy = gpa(y);
45     if(fx == fy) return;
46     int x1 = dim[fx],x2 = dim[fy];
47     pa[fx] = fy;
48     dim[fy] = (x1+1>>1) + (x2+1>>1) + 1;
49     dim[fy] = max(dim[fy],max(x1,x2));
50 }
51 
52 //baosou zhaozhijing
53 //only in init
54 int dis[N],vis[N];
55 int findfur(int s) {
56     dis[s] = 0,vis[s] = s;
57     int ans = s;
58     queue<int> q;
59     q.push(s);
60     while(!q.empty()) {
61         int x = q.front();
62         q.pop();
63         for(int i = head[x];i;i = nxt[i]) {
64             int sn = mo[i];
65             if(vis[sn] == s) continue;
66             vis[sn] = s,dis[sn] = dis[x] + 1;
67             q.push(sn);
68             if(dis[sn] > dis[ans]) ans = sn;
69         }
70     }
71     return ans;
72 }
73 
74 int Dim(int x) {
75     return dis[findfur(findfur(x))];
76 }
77 
78 int main() {
79     n = read(),m = read(),T = read();
80     rep(i,1,n) pa[i] = i;
81     rep(i,1,m) {
82         int x = read(),y = read();
83         add(x,y);
84         x = gpa(x),y = gpa(y);
85         if(x ^ y) pa[x] = y;
86     }
87     rep(i,1,n) if(pa[i] == i) dim[i] = Dim(i);
88     rep(i,1,T) {
89         bool op = read() - 1;
90         if(op) Merge(read(),read());
91         else printf("%d
",dim[gpa(read())]);
92     }
93     return 0;
94 }
View Code
> 别忘了 总有人在等着你
原文地址:https://www.cnblogs.com/yuyanjiaB/p/9687651.html