luoguP2195 HXY造公园 树的直径 并查集

time cost:65min

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

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cmath>
  5 #define rep(i,a,n) for(int i = a;i <= n;i++)
  6 #define per(i,n,a) for(int i = n;i >= a;i--)
  7 #define ms(a,b) memset(a,b,sizeof a)
  8 using namespace std;
  9 typedef long long ll;
 10 ll read() {
 11     ll as = 0,fu = 1;
 12     char c = getchar();
 13     while(c < '0' || c > '9') {
 14         if(c == '-') fu = -1;
 15         c = getchar();
 16     }
 17     while(c >= '0' && c <= '9') {
 18         as = as * 10 + c - '0';
 19         c = getchar();
 20     }
 21     return as * fu;
 22 }
 23 const int N = 300005;
 24 //head
 25 int n,m,q;
 26 int head[N],mo[N],nxt[N],cnt;
 27 inline void add(int x,int y) {
 28     mo[++cnt] = y;
 29     nxt[cnt] = head[x];
 30     head[x] = cnt;
 31     return;
 32 }
 33 
 34 int pa[N];
 35 int gpa(int x) {
 36     if(pa[x] == x) return x;
 37     return pa[x] = gpa(pa[x]);
 38 }
 39 int path[N];
 40 void Merge(int x,int y) {
 41     int fx = gpa(x),fy = gpa(y);
 42     if(fx == fy) return;
 43     int u1 = path[fx];
 44     int u2 = path[fy];
 45     pa[fx] = fy;
 46     //shang_qu_zheng
 47     path[fy] = (u1+1 >> 1) + (u2+1 >> 1) + 1;
 48     path[fy] = max(max(u1,u2),path[fy]);
 49     return;
 50 }
 51 
 52 int dis[N],flag[N];
 53 int que[N];
 54 int finddim(int str) {
 55     dis[str] = 0,flag[str] = str,que[que[0] = 1] = str;
 56     int fur = str;
 57     rep(i,1,que[0]) {
 58     int x = que[i];
 59     for(int i = head[x];i;i = nxt[i]) {
 60         int sn = mo[i];
 61         if(flag[sn] == str) continue;
 62         flag[sn] = str;
 63         que[++que[0]] = sn;
 64         dis[sn] = dis[x] + 1;
 65         if(dis[sn] > dis[fur]) fur = sn;
 66     }
 67     }
 68     return fur;
 69 }
 70 int Dim(int x) {
 71     int tmp = finddim(x);
 72     return dis[finddim(tmp)];
 73 }
 74 
 75 int main() {
 76     n = read(),m = read();
 77     int T = read();
 78     rep(i,1,n) pa[i] = i;
 79     rep(i,1,m) {
 80     int x = read();
 81     int y = read();
 82     add(x,y),add(y,x);
 83     int fx = gpa(x);
 84     int fy = gpa(y);
 85     if(fx != fy) pa[fx] = fy;
 86     }
 87     rep(i,1,n) if(i == gpa(i)) path[i] = Dim(i);
 88     rep(i,1,T) {
 89     bool op = read() - 1;
 90     if(!op) {
 91         int x = read();
 92         printf("%d\n",path[gpa(x)]);
 93     } else {
 94         int x = read();
 95         int y = read();
 96         Merge(x,y);
 97     }
 98     }
 99     return 0;
100 }

猜你喜欢

转载自www.cnblogs.com/yuyanjiaB/p/9687651.html