牛客2021训练联盟热身训练赛Interstellar Love(并查集)

题目链接

题目描述 

After two years of sharing a bedroom with you in a college dorm, Jeff finally has his own room. Excited about inviting girls over to his room, he ponders over what decorations the fairer sex will enjoy.1 He decides upon setting up a “fake” planetarium with a black ceiling and glow in the dark stars that form constellations. Unfortunately, in his haste, he has made several “errors” in setting up his constellations. See, everyone knows that constellations don’t have cycles in them. Instead, whenever we visually connect the stars together with lines, a tree is always formed. (A cycle is formed when you can start at a star and, using connections, go to one or more other stars and then end up at the original star.)

Since you were Jeff’s roommate for two years, you figure you’ll help him fix his constellations. Your job will be twofold: to count the number of constellations Jeff has, and to report how many of them have cycles and need to be fixed. A constellation consists of multiple stars that are all connected to one another (directly or indirectly). A constellation that needs fixing is simply one that has a cycle.

The Problem:

Given several configurations of stars and connections between stars, determine how many constellations are defined in each configuration and how many need fixing.

输入描述:

The first input line contains a positive integer, n (n ≤ 100), indicating the number of night skies to  consider.   The  first  line  of  each  night  sky  contains  two positive  integers,  s  (s ≤  1000), representing  the  number  of  stars  for  this  night  sky,  and  c  (c  ≤  10000),  representing  the  total number  of  connections  between  pairs  of  stars  for  this  night  sky.  Each  of the following c input lines  contains  two  distinct positive integers representing a single connection between two stars. The stars in each test case will be numbered 1 through s, inclusive.  A connection is considered bidirectional, thus, if a is connected to b, b is connected to a.  Assume that all connections in a data set are distinct, i.e., no duplicates.  Also assume that there will never be a connection from a star to itself.

1 This is based on a true story.  The person who is the inspiration for this story did, in fact, major in Planetary Science and make his room’s ceiling a relatively accurate depiction of the night sky, as seen in Boston circa 1995.

输出描述:

For each test case, just output a line with the following format:
Night sky #k: X constellations, of which Y need to be fixed.
where  k is  the  number  of  the  night  sky,  starting  at  1,  X is  the  total  number  of  constellations described in that night sky, and Y is how many of those constellations contain a cycle.
Leave a blank line after the output for each test case. 

输入

3
5 4
1 2
1 3
2 3
4 5
8 5
1 2
3 4
6 7
6 8
8 7
3 2
1 2
1 3

输出

Night sky #1: 2 constellations, of which 1 need to be fixed. 

Night sky #2: 3 constellations, of which 1 need to be fixed. 

Night sky #3: 1 constellations, of which 0 need to be fixed.

说明

Note:In the second example, star number 5 is not connected to any other stars. This staron its own is NOT counted as a constellation, leaving only {1,2}, {3,4}and {6,7,8} as constellations, of which only the last one needs tobe fixed.

并查集算法,注意插入时判断,如果待插入的两个结点的根结点相同,则会形成环路:

AC代码:

#include<bits/stdc++.h>  //并查集
#define int long long
using namespace std;

const int maxn = 1234;
int n, s, c, a, b, k = 1;
int father[maxn], cnt[maxn];   
bool vis[maxn];
int res1 = 0, res2 = 0;   //星座数和需要修理数

int findFather(int u){
	if(father[u] != u) father[u] = findFather(father[u]);
	return father[u];
}

void init(int u){
	res1 = 0, res2 = 0;
	for(int i = 1; i <= u; i++){
		father[i] = i;
		cnt[i] = 1;	
	} 
	memset(vis, false, sizeof vis);
}

void Union(int a, int b){
	father[findFather(a)] = findFather(b);
	cnt[b] += cnt[a];
}

signed main(){
	cin >> n;
	while(n--){
		cin >> s >> c;
		init(s);
		for(int i = 0; i < c; i++){
			cin >> a >> b;
			int pa = findFather(a), pb = findFather(b);
			if(pa != pb){
				Union(pa, pb);
				if(vis[pa] or vis[pb])    //若已经是个环路,则插上去的结点也相当于环路上的结点
					vis[pb]=true;
			}
			else vis[pa] = true;   //标记存在环的集合(待插入的两个结点的根结点相同,则会形成环路)
		}
		for(int i = 1; i <= s; i++)
			if(father[i] == i and cnt[i] > 1){  //是根结点且集合里有多于1个顶点元素才是星系
				++res1;
				if(vis[i]) ++res2;
			} 
		printf("Night sky #%lld: %lld constellations, of which %lld need to be fixed.\n\n", k++, res1, res2);
	}
	
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值