第一题

链接:https://www.nowcoder.com/questionTerminal/7c29cdfa28274c86afc9e88c07448a10
来源:牛客网
猫猫有脾气
顶点数目必须足够大  啊啊啊!!!

链接:https://www.nowcoder.com/questionTerminal/7c29cdfa28274c86afc9e88c07448a10
来源:牛客网
#include<cstdio>
 
using namespace std;
 
const int MAX=1000010;
int father[MAX];
int height[MAX];
bool visit[MAX];
 
void Init(){
    for(int i=1;i<MAX;i++){
        father[i]=i;
        height[i]=0;
        visit[MAX]=false;
    }
}
 
int Find(int x){
    if(x!=father[x]){
        father[x]=Find(father[x]);
    }
    return father[x];
}
void Union(int x,int y){
    x=Find(x);
    y=Find(y);
    if(x!=y){
        if(height[x]<height[y]){
            father[x]=y;
        }else if(height[x]>height[y]){
            father[y]=x;
        }else{
            father[y]=x;
            height[x]++;
        }
    }
}
 
int main(){
    Init();
    int MaxNum=0;
    int x,y;
    while(scanf("%d%d",&x,&y)!=EOF){
         
        Union(x,y);
        visit[x]=true;
        visit[y]=true;
        MaxNum=MaxNum>x?MaxNum:x;//为了缩小下面的遍历范围 保留这一个文件中最大编号的节点
        MaxNum=MaxNum>y?MaxNum:y;
    }
    int component=0;
    for(int i=1;i<=MaxNum;i++){
        if(!visit[i])
            continue;
        if(father[i]==i)
            component++;
    }
    printf("%d\n",component);
    return 0;
}

全部评论
mywgo 并查集的板子 #include<iostream> #include<vector> #include<map> #include<algorithm> using namespace std; map<int,int> father;  //通过散列表map实现的father数组 map<int,int> height;  //记录每个节点的高度 int find(int x){     if(father.find(x)!=father.end()){         if(father[x]!=x)             father[x]=find(father[x]);  //路径压缩(最后自己通过例子模拟下过程)     }     else{//如果还没有出现的新节点。把father设成他自己(表示根节点),height设成0         father[x]=x;         height[x]=0;     }     return father[x]; } void Union(int a,int b){//合并函数     a=find(a);     b=find(b);     if(a!=b){         if(height[a]>height[b])             father[b]=a;         else if(height[b]>height[a])             father[a]=b;         else{             father[a]=b;             height[a]++;         }     } } int main() {     int i,j;     while(cin>>i>>j){         Union(i,j);     }     int sum=0;     for(auto it=father.begin();it!=father.end();it++){         if(it->first==it->second)sum++;  //只要有一个父亲是本身的就说明是根节点     }     cout<<sum<<endl;     return 0;    }
点赞 回复 分享
发布于 2022-10-13 22:01 福建

相关推荐

joe2333:怀念以前大家拿华为当保底的日子
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务