首页 > 代码库 > HDU 2473 Junk-Mail Filter 删点并查集
HDU 2473 Junk-Mail Filter 删点并查集
题目来源:HDU 2473 Junk-Mail Filter
题意:2中操作 M x, y 将x,y 合并到一个集合 S x 将x从所在的集合去掉 自己成为一个集合 最后求有多少个集合
思路:删点不好做 可以如果0 1 2在一个集合 可以定义个数组映射 就是每个点所对应实际的点 开始是a[0] = 0 a[1] = 1 a[2] = 2 说明都是自己
现在要去掉2 可以定义一个新的点 原来的要删的点留着 a[2] = 3 现在的3就是原来所对应的2 原来的集合堕落一个点 每次合并的时候处理a数组
#include <cstdio> #include <cstring> using namespace std; const int maxn = 1100010; int f[maxn], a[maxn], flag[maxn]; int cnt; void init(int n) { for(int i = 1; i <= n; i++) f[i] = a[i] = i; cnt = n; memset(flag, 0, sizeof(flag)); } int find(int x) { if(x != f[x]) return f[x] = find(f[x]); return f[x]; } void merge(int x, int y) { x = find(x); y = find(y); if(x != y) f[x] = y; } void del(int x) { find(a[x]); f[++cnt] = cnt; a[x] = cnt; } int main() { int cas = 1; int T; int n, m; while(scanf("%d %d", &n, &m) && (n||m)) { init(n); while(m--) { char s[10]; scanf("%s", s); if(s[0] == 'S') { int x; scanf("%d", &x); x++; del(x); } else { int x, y; scanf("%d %d", &x, &y); x++, y++; merge(a[x], a[y]); } } int ans = 0; for(int i = 1; i <= n; i++) { int x = find(a[i]); if(!flag[x]) { ans++; flag[x] = 1; } } printf("Case #%d: %d\n", cas++, ans); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。