PAT顶级 1014 Circles of Friends (35分)(并查集+BFS)

欢迎大家访问我的PAT TOP解题目录~

https://blog.csdn.net/qq_45228537/article/details/103671868

题目链接:

1014 Circles of Friends (35分)

思路:

首先使用并查集就能很快求出集合个数;
然后再对每个点BFS即可,虽然O(n2)O(n^2),但是毕竟n不大;

代码:

#include<bits/stdc++.h>

using namespace std;

const int maxn = 1234;
int n, rcd[maxn], par[maxn], rk[maxn];
vector<int> G[maxn];

void init_(){ for(int i = 1; i <= n; i++) par[i] = i; }
int find(int x){
	if(x == par[x]) return x;
	else return par[x] = find(par[x]);
}
void unite(int x, int y){
	x = find(x);
	y = find(y);
	if(x == y) return;
	if(rk[y] > rk[x]) par[x] = y;
	else{
		par[y] = x;
		if(rk[x] == rk[y]) ++rk[x];	
	}
}
void bfs(int u){
	vector<int> dis(n + 1);
	queue<int> que;
	que.push(u);
	while(!que.empty()){
		int now = que.front();
		que.pop();
		for(int& x : G[now]){
			if(x != u && !dis[x]) que.push(x), dis[x] = dis[now] + 1;
		}
	}
	for(int& x : dis) rcd[u] = max(rcd[u], x - 1);
}

int main(){
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);
#endif	
	scanf("%d", &n);
	init_();
	for(int i = 1; i <= n; i++){
		int k, p;
		scanf("%d", &k);
		while(k--){
			scanf("%d", &p);
			G[i].push_back(p);
			G[p].push_back(i);
			unite(i, p);
		}
	}
	int num = 0, ans = 0;
	for(int i = 1; i <= n; i++){
		bfs(i);
		ans = max(ans, rcd[i]);
		if(i == find(i)) ++num;
	}
	printf("%d %d\n", num, ans);
	return 0;
}
posted @ 2020-01-07 14:09  YuhanのBlog  阅读(189)  评论(0编辑  收藏  举报