zoukankan      html  css  js  c++  java
  • 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
    ", num, ans);
    	return 0;
    }
    
  • 相关阅读:
    点分治 (等级排) codeforces 321C
    树上点分治 poj 1741
    判断点在直线的左侧还是右侧
    树的重心
    链式前向星
    树上点的分治
    构造 素数
    二进制 + 模拟
    枚举 + 三分 (游标)
    枚举 + 三分
  • 原文地址:https://www.cnblogs.com/yuhan-blog/p/12308696.html
Copyright © 2011-2022 走看看