离线处理,并查集,拆网

Contest (nefu.edu.cn)
Problem:B
Time Limit:1000ms
Memory Limit:65535K

Description

敌人的通讯网持续遭我袭击,请根据已经被切断的边来判断敌人的两个节点是否连通。

给定一个无向图,保证图中无重边自环,不保证图初始联通。
接下来q行,每行一个操作:
1 a b:查询a b结点是否联通,若是请输出yes,否则输出no
0 a:代表下表为a的边已经被摧毁

请注意:点的编号为[1,n],边的编号为[0,m)

Input

第一行三个整数n,m,q(1<n<=1e5,1<m,q<=1e6)
接下来m行,每行两个整数代表该边所连接的点编号,边的编号按输入顺序从0递增;
接下来q行,每行一个操作,格式如上所述。

Output

对于每一个操作1,输出一行yes或no

Sample Input

5 7 8
1 4
1 2
1 5
2 5
2 4
3 4
4 5
0 5
0 0
0 4
1 4 3
1 3 1
0 1
1 2 5
1 1 3

Sample Output

no
no
yes
no

Hint

 

Source

Kisaragi & _Yu

解析:离线处理,并查集

这道题让我们判断两点之间是否联通,我们可以想到用并查集来判断;

但由于并查集擅长的是建边,而不是题目所讲的拆边,所一这道题并不能直接使用并查集;

这里我们采用离线处理的方法:

将所有的数据先读入并存储起来,并且处理成最后的状态,我们从最后的状态往回处理,即先将边拆掉,再将边一条一条建回去,这样就将题目转换成了并查集擅长的形式

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>

using namespace std;
typedef long long LL;
const int M = 1e6 + 5, N = 1e5 + 5;
int n, m, q;
typedef struct st {
	int v, u,f;
}st;
st arr[M];
struct str {
	int op, a, b;
}str[M];

int fa[N];

int find(int a) {
	if (fa[a] == a) {
		return a;
	}
	return fa[a] = find(fa[a]);
}

void merge(int a, int b) {
	int x = find(fa[a]);
	int y = find(fa[b]);
	fa[x] = y;
}

int main() {
	cin >> n >> m >> q;
	for (int i = 0; i < m; i++) {
		scanf("%d%d", &arr[i].u, &arr[i].v);
	}
	for (int i = 0; i < q; i++) {
		scanf("%d", &str[i].op);
		if (str[i].op) {
			scanf("%d%d", &str[i].a, &str[i].b);
		}
		else {
			scanf("%d", &str[i].a);
			arr[str[i].a].f = 1;
		}
	}
	for (int i = 1; i <= n; i++) {
		fa[i] = i;
	}
	for (int i = 0; i < m; i++) {
		if (arr[i].f!=1) {
			merge(arr[i].u, arr[i].v);
			
		}
	}
	stack<string>s;
	for (int j = q - 1; j >= 0; j--) {
		if (str[j].op) {
			if (find(fa[str[j].a]) == find(fa[str[j].b])) {
				s.push("yes");
			}
			else {
				s.push("no");
			}
		}
		else {
			int t = str[j].a;
			merge(arr[t].u, arr[t].v);
		}
	}
	while (!s.empty()) {
		printf("%s\n", s.top().c_str());
		s.pop();
	}
	return 0;
}

posted @ 2023-09-05 15:42  Landnig_on_Mars  阅读(13)  评论(0编辑  收藏  举报  来源