Brute Force!!! It is easy to think of each color to build a diagram, and then check the set maintenance of connectivity.
The problem is that the color has O (m), and the number of points per color is O (n), so the space for the check set can only be reused.
However, space in O (m) can be used to retain useful connected block information.
The subsequent processing can draw on the idea of chunking.
The number of connected blocks that the point v belongs to is B (v), and for the query for x, Y, depending on the connected block information of the point, the time of the O (max (b (x), B (y))) can be answered.
Set a threshold of B, for B (v) >b, pre-treatment, less than B on the violent answer.
Because an edge increases by up to two B (v) values, all B (v) and is O (M). A maximum of m/b v satisfies B (v) greater than B, and for each such v,o (m) the calendar passes once.
The complexity of the two parts is O (m/b*m + b*q), similar to the block of the extraction, take B = M/sqrt (q), the complexity of O (m*sqrt (q)).
/**********************************************************--------------Alfheim--------------* * Author Abyssalfish ***********************************************************/#include<bits/stdc++.h>using namespaceStd;typedefLong Longll;Const intMAXN = 1e5+5, MAXM = 1e5+5;intPA[MAXN], RAK[MAXN];intFdintx) { returnPA[X]? PA[X] =FD (Pa[x]): x;} InlinevoidJointintAintb) { intx = FD (a), y =FD (b); if(X! =y) { if(Rak[x] <Rak[y]) {Pa[x]=y; } Else{Pa[y]=x; if(Rak[x] = = Rak[y]) rak[x]++; } }}intA[MAXM],B[MAXM];BOOLVIS[MAXN];intHD_C[MAXN], Nx_e[maxm];inlinevoidAdd_e (intClinti) {Nx_e[i]=HD_C[CL]; HD_C[CL]=i;} typedef vector<int>block;typedef Vector<int>V_int;vector<Block>BLC; Block Tmp[maxn];v_int In_blk[maxn];inlinevoidADD_BLC (intx) { if(!Vis[x]) {Vis[x]=true; TMP[FD (x)].push_back (x); }}inlinevoidDumpintx) { if(Tmp[x].size () >1) {blc.push_back (tmp[x]); Tmp[x].clear (); } if(Vis[x]) {vis[x]=false; RAK[X]= Pa[x] =0; }}Constuint32_t MAXB =448;intans[maxb+5][MAXN];intID[MAXN];//#define LOCALintMain () {#ifdef LOCAL freopen ("In.txt","R", stdin);#endif //cout<< (2*maxm/sqrt (2*MAXM)); intn,m,q; scanf ("%d%d",&n,&m); uint32_t B= Floor (2*M/SQRT (2*m)); inti,j; for(i =1; I <= m; i++) {scanf ("%d%d%d",a+i,b+i,&j); Add_e (J,i); } for(i =1; I <= m; i++){ for(j = hd_c[i]; j; j =Nx_e[j]) {Joint (a[j],b[j]); } for(j = hd_c[i]; j; j =Nx_e[j]) {ADD_BLC (a[j]); ADD_BLC (B[j]); } for(j = hd_c[i]; j; j =Nx_e[j]) {dump (a[j]); Dump (B[j]); } } for(i =0; I < (int) Blc.size (); i++){ for(Auto V:blc[i]) {in_blk[v].push_back (i); } } intid_cnt =0; for(i =1; I <= N; i++){ if(In_blk[i].size () >B) {Id[i]= ++id_cnt; for(Auto B_id:in_blk[i]) { for(Auto v:blc[b_id]) {Ans[id_cnt][v]++; } }}} scanf ("%d",&q); while(q--){ intx, y; scanf"%d%d",&x,&y); intRes; if(Id[x]) res =Ans[id[x]][y]; Else if(Id[y]) res =Ans[id[y]][x]; Else{res= i = j =0; V_int&x = In_blk[x], &y =In_blk[y]; N= X.size (); m =y.size (); while(I < n && J <m) { if(X[i] = =Y[j]) {Res++; i++; J + +; } Else{X[i]< Y[j]? i++: J + +; }}} printf ("%d\n", RES); } return 0;}
Mr Kitayuta ' s colorful Graph