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 }