题意
初始给定两个点数一样的空图,在每个时刻会有一些连边操作,在每个时刻,判断两个图任意两点的连通性是否相同
思路
用并查集维护连通性,用 队列 维护操作序列。例如,每次在图1连u, v。我们可以认为,是让u, v连通,并把这条边加入图2的队列。如果图2 u, v不连通,那么就保存在图2的队列中,用两个队列让两个图在一次操作前是面对相同局面的,即如果在加入本次操作对应的这条边之前,如果把两个队列都清空,此时两个图是相同连通性的,即等价。
或者我们可以这样想:每一次连u, v的操作,是维护u所在集合和v所在集合的连通性,那么我们只要把这个u, v连通性的询问放在另一个图的队列里,连通就pop掉,不连通就存在队列中,不从边的角度理解,而是从集合的角度理解。
std中有个很好的处理就是面对多个含义相同的数组(fa1, fa2),用一个数组指针做函数名,有效简化了代码。
手残把find(fa1, u) == find(fa1, v) 打错了,要注意判断连不连通是用find函数啊!
代码
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<set>
#define NDEBUG
#include <assert.h>
using namespace std;
typedef vector<int> vi;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
inline int read() {
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
#define endl '\n'
#define rd read()
#define pb push_back
#define mst(a, b) memset((a), (b), sizeof(a));
#define inf 0x3f3f3f3f
#define linf 0x3f3f3f3f3f3f3f3f
#define ls (u << 1)
#define rs (u << 1 | 1)
#define mod ((int)1e9+7)
#define maxn (int)(1e5+5)
int n, m;
int fa1[maxn], fa2[maxn];
void init(int *fa) {for(int i = 0; i < maxn; ++i) fa[i] = i;}
int find(int *fa, int x) {return x == fa[x] ? x : fa[x] = find(fa, fa[x]);}
struct edge {int u, v;};
void merge(int *fa, int x, int y) {
x = find(fa, x), y = find(fa, y);
if(x != y) fa[x] = y;
}
queue<edge> q1, q2;
int main() {
#ifndef ONLINE_JUDGE
freopen("D:\\Chrome Downloadings\\input.txt", "r", stdin);
freopen("D:\\Chrome Downloadings\\output.txt", "w", stdout);
#endif
cin >> n >> m;
init(fa1), init(fa2);
for(int i = 1; i <= m; ++i) {
int op = rd, u = rd, v = rd;
if(op == 1) merge(fa1, u, v), q2.push({u, v});
else merge(fa2, u, v), q1.push({u, v});
while(!q1.empty()) {
if(find(fa1, q1.front().u) == find(fa1, q1.front().v)) q1.pop();
else break;
}
while(!q2.empty()) {
if(find(fa2, q2.front().u) == find(fa2, q2.front().v)) q2.pop();
else break;
}
puts(q1.empty() && q2.empty() ? "A" : "B");
}
return 0;
}