WUSTOJ 1940 打击犯罪 【并查集】

题目来源:http://acm.wust.edu.cn/problem.php?id=1940&soj=0
在这里插入图片描述
★这题本来是不想写博客的,原因是:之前我也不会写,我搜了几篇博客都是WA的代码,我就发一波叭,感谢我滴同学的帮助~

相关知识:

并查集是一种集合思想,将相关的一类放在一个集合中,这里我通过数组来实现(还可以用链表实现)
用到了vector动态数组,用处就是减少内存,下图就是使用前(下)使用后对比(上)
在这里插入图片描述
当然这个不影响时间的,我后来还优化了其他一些东西
还有就是我改掉了以前的习惯,我不用万能头(#include<bits/stdc++.h>)了,听说内存占得更多,而且用习惯了也不好,不然忘记了根本。

思路:

和其他博客不一样,我用的是从后往前添加,而不是从前往后重新来过。当然,我也觉得那些博客貌似没啥问题,但就是过不了 num保存一个集合的成员数,dad理解为一个集合的头爸爸 叭,废话不多说,上代码~

代码:

#include<iostream> 
#include<cstring> 
#include<vector> 
using namespace std; 
int dad[2005],num[2005]; 
vector<int> f[2005]; 
int seek(int k) 
{ 
    if(dad[k]==k) return dad[k]; 
    return seek(dad[k]); 
} 
int main() 
{ 
    int n; 
    while(cin>>n){ 
        for(int i=1;i<=n;i++) {dad[i]=i; num[i]=1; f[i].clear();} 
        for(int i=1;i<=n;i++){ 
            int m;cin>>m; 
            for(int j=1;j<=m;j++){ 
                int a;cin>>a; 
                f[i].push_back(a); 
            } 
        } 
        for(int i=n;i>=1;i--){ 
            int a=seek(i); 
            for(int j=1;j<=f[i].size();j++){ 
                if(f[i][j-1]>i){ 
                    int b=seek(f[i][j-1]); 
                    if(a!=b) {dad[b]=a; num[a]+=num[b];} 
                } 
            } 
            for(int j=1;j<=n;j++) 
            if(num[j]>(n>>1)){ 
                cout<<j<<endl; 
                goto hhh; 
            } 
        } 
        hhh:; 
    } 
    return 0; 
} 

猜你喜欢

转载自blog.csdn.net/weixin_43890662/article/details/88110698