BZOJ4998: 星球聯盟 並查集
阿新 • • 發佈:2018-12-10
Descripition 給你一張圖,每次加一條邊,加完邊後,問這兩個點是否屬於同一個點雙,不是輸出No,否則輸出點雙的點數。
Sample Input 5 3 4 1 2 4 3 4 5 2 3 1 3 4 5 2 4
Sample Output No 3 2 5
對於每一次加邊,就相當於把當前樹上的一段合成一點,這個可用並差集搞。 問題是如何構造出一棵樹,這個也很簡單,一開始先加完所有的邊,建出一棵樹即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int read() {
int s = 0, f = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * f;
}
struct node {
int x, y;
} q1[210000], q2[210000 ];
struct edge {
int x, y, next;
} e[410000]; int len, last[210000];
int fa[210000], dep[210000], f[210000];
int ff[210000], tot[210000];
int findfa(int x) {
if(fa[x] != x) fa[x] = findfa(fa[x]);
return fa[x];
}
int findfa2(int x) {
if(ff[x] != x) ff[x] = findfa2(ff[x]);
return ff[x];
}
void Merge(int x, int y) {
x = findfa2(x), y = findfa2(y);
while(x != y) {
if(dep[x] > dep[y]) swap(x, y);
int fy = findfa2(f[y]);
ff[y] = fy; tot[fy] += tot[y];
y = fy;
}
}
void ins(int x, int y) {
e[++len].x = x; e[len].y = y;
e[len].next = last[x]; last[x] = len;
}
void dfs(int x) {
for(int k = last[x]; k; k = e[k].next) {
int y = e[k].y;
if(y != f[x]) f[y] = x, dep[y] = dep[x] + 1, dfs(y);
}
}
int main() {
int n = read(), m = read(), q = read();
for(int i = 1; i <= n; i++) fa[i] = i;
for(int i = 1; i <= m; i++) {
int x = read(), y = read();
int fx = findfa(x), fy = findfa(y);
if(fx != fy) ins(x, y), ins(y, x), fa[fx] = fy;
q1[i].x = x, q1[i].y = y;
}
for(int i = 1; i <= q; i++) {
int x = read(), y = read();
int fx = findfa(x), fy = findfa(y);
if(fx != fy) ins(x, y), ins(y, x), fa[fx] = fy;
q2[i].x = x, q2[i].y = y;
} for(int i = 1; i <= n; i++) if(!dep[i]) dep[i] = 1, dfs(i);
for(int i = 1; i <= n; i++) fa[i] = i, ff[i] = i, tot[i] = 1;
for(int i = 1; i <= m; i++) {
int x = q1[i].x, y = q1[i].y;
int fx = findfa(x), fy = findfa(y);
if(fx != fy) fa[fx] = fy;
else Merge(x, y);
}
for(int i = 1; i <= q; i++) {
int x = q2[i].x, y = q2[i].y;
int fx = findfa(x), fy = findfa(y);
if(fx != fy) fa[fx] = fy, printf("No\n");
else Merge(x, y), printf("%d\n", tot[findfa2(x)]);
}
return 0;
}