FZU - 2155 - 盟国 (带删除的并查集~~)

Problem 2155 盟国

Accept: 140    Submit: 464

Time Limit: 5000 mSec    Memory Limit : 32768 KB

 Problem Description

世界上存在着N个国家,简单起见,编号从0~N-1,假如a国和b国是盟国,b国和c国是盟国,那么a国和c国也是盟国。另外每个国家都有权宣布退盟(注意,退盟后还可以再结盟)。

定义下面两个操作:

“M X Y” :X国和Y国结盟

“S X” :X国宣布退盟

 Input

多组case。

每组case输入一个N和M (1 ≤ N ≤ 100000 , 1 ≤ M ≤ 1000000),N是国家数,M是操作数。

接下来输入M行操作

当N=0,M=0时,结束输入

 Output

对每组case输出最终有多少个联盟,格式见样例。

 Sample Input

5 6

M 0 1

M 1 2

M 1 3

S 1

M 1 2

S 3

3 1

M 1 2

0 0

 Sample Output

Case #1: 3

Case #2: 2

Submit  Back  Status  Discuss

带删除操作的并查集。。

AC代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 2000005;			//注意这里M可以到1000000,所以maxn要开大点
int pa[maxn], real[maxn];//用real数组标记每个点的真实位置,删除一个点后只需将其放于末尾即可
int vis[maxn];

int find(int x) {
	return pa[x] != x ? pa[x] = find(pa[x]) : x;
}

int main() {
	int n, m, cas = 1;
	while(scanf("%d %d", &n, &m) == 2 && (n || m)) {
		for(int i=0; i<n; i++)
			pa[i] = real[i] = i;
		memset(vis, 0, sizeof(vis));

		char fun[5];
		int a, b, sum = n;
		while(m--) {
			scanf("%s", fun);
			if(fun[0] == 'M') {
				scanf("%d %d", &a, &b);
				int x = find(real[a]), y = find(real[b]);
				if(x != y) pa[x] = y;
			} else {
				scanf("%d", &a);
				pa[sum] = sum;
				real[a] = sum++;	//相当于把a从原来的位置删除,记录新的位置
			}
		}

		int ans = 0;
		for(int i=0; i<n; i++) {
			int x = find(real[i]);
			if(!vis[x]) {
				vis[x] = 1;
				ans++;
			}
		}
		printf("Case #%d: %d\n", cas++, ans);
	}
	return 0;
} 
时间: 2024-10-03 20:39:20

FZU - 2155 - 盟国 (带删除的并查集~~)的相关文章

UVA - 11987 Almost Union-Find(带删除的并查集)

Almost Union-Find Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Problem A Almost Union-Find I hope you know the beautiful Union-Find structure. In this problem, you're to implement something simil

【uva11987】带删除的并查集

题意:初始有N个集合,分别为 1 ,2 ,3 .....n.有三种操件1 p q 合并元素p和q的集合2 p q 把p元素移到q集合中3 p 输出p元素集合的个数及全部元素的和. 题解: 并查集.只是并查集中并没有删除的操作.所以就需要将删除的这个点的影响降到0,也就是给删除的点申请一个新的id,以后都是用这个新的id来表示这个点,这样原来的那个集合里的点p就没意义,自然影响就为0. 就我写了debug那里比较坑.. 代码: 1 #include<cstdio> 2 #include<c

FZU 2155 盟国

 Problem 2155 盟国  Problem Description 世界上存在着N个国家,简单起见,编号从0~N-1,假如a国和b国是盟国,b国和c国是盟国,那么a国和c国也是盟国.另外每个国家都有权宣布退盟(注意,退盟后还可以再结盟). 定义下面两个操作: "M X Y" :X国和Y国结盟 "S X" :X国宣布退盟  Input 多组case. 每组case输入一个N和M (1 ≤ N ≤ 100000 , 1 ≤ M ≤ 1000000),N是国家数,

Poj 1182种类(带权)并查集

题目链接 食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44316 Accepted: 12934 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是

poj 1182 食物链 (带关系的并查集)

  食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44835 Accepted: 13069 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类.

带偏移量的并查集

//带偏移量的并查集≈并查集补集 //维护各点到父节点的距离 可用来分类 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> using namespace std; int n,f[1001],d[1001]; int find(int x) { if(x==f[x])

[HDU 3712] Fiolki (带边权并查集+启发式合并)

[HDU 3712] Fiolki (带边权并查集+启发式合并) 题面 化学家吉丽想要配置一种神奇的药水来拯救世界. 吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[i]克的第i种物质.吉丽需要执行一定的步骤来配置药水,第i个步骤是将第a[i]个瓶子内的所有液体倒入第b[i]个瓶子,此后第a[i]个瓶子不会再被用到.瓶子的容量可以视作是无限的. 吉丽知道某几对液体物质在一起时会发生反应产生沉淀,具体反应是1克c[i]物质和1克d[i]物质生成2克沉淀,一直进行直

[POJ 1988] Cube Stacking (带值的并查集)

题目链接:http://poj.org/problem?id=1988 题目大意:给你N个方块,编号从1到N,有两种操作,第一种是M(x,y),意思是将x所在的堆放到y所在的堆上面. 第二种是C(x),意思是数x方块下面有多少个方块. 把两堆合成一堆,这个可以用并查集来实现,问题是,怎么样维护x方块下面有多少个方块呢? 先来分析一下题目,按照样例,我们有6个方块,1,2,3,4,5,6. 令Cnt(x) = C(x)+1. 先执行M(1,6),此时Cnt(1) = 2, Cnt(6) = 1 再

FZU 2192 位置信息挖掘 (种类并查集)

题目链接:click here~~ [题目大意]: O2O即Online To Offline,是指将线下的商务机会与互联网结合,让互联网成为线下交易的前台.这些商务机会主要是偏服务类的商品,例如汽车售后服务.摄影服务.餐饮.电影等,其特色是线上购买.线下服务. 因此,对这类垂直行业的商品做移动推荐时,用户和商品的位置信息显得格外重要.但是,可能存在用户.商品的位置信息缺失的情况,例如:用户不共享位置信息.商家未填写位置信息-- 现在,Jason给出用户在移动端的购买行为数据,以及商品集合,希望