zoukankan      html  css  js  c++  java
  • 并查集

    int pre[N]; //代表x的上级 
    int zxy(int x) //x要去找他的老大,看看他和另y是不是同一个帮派 
    {
        int r = x; //让r去找x的上级 
        while (pre[r] != r) //如果他的上级不是他自己 
        r = pre[r]; //就令r的上级去找他的上级,以此类推
        
        int i = x, j;
        while (i != r) //如果r的上级不是老大 
        {
            j = pre[i]; //这时来了个j说:我来帮r的上级来管理下属,r的上级你去找你的上级吧 
            pre[i] = r; //但是r却说:j大哥,不用你在这帮忙,
                        //我跟我的上级(pre[r])说了,他先让我暂时帮他管理一下,就不用麻烦您了。 
                        //这里就相当于r直接升了一个等级,占了他上级(pre[r])的位置。
                        //以此类推,就相当于r直接去找老大了(仔细想想对不对?)。 
            i = j; //j这时说:不过你的下属没人管了啊,我去帮你管管吧,你就去找老大吧。 
        } 
        return r; //老大现身(登登登----登---------) 
    } 
    
    int zhoier(int x , int y) //让x和y成为一个帮派的 
    {
        int fx = zxy(x) , fy = zxy(y); //x和y通过zxy这个强大的天神终于找到了他们的老大
        if(fx != fy) //如果x和y的老大不是一个人 
            pre[fx] = fy;  //因为x的老大比较淡泊名利,所以就让y的老大当帮主,所以x的老大的上级就成了y的老大
                           //帮派合并完成!!! 
    } 

    并查集就是用来解决合并集合的,只要能灵活运用以上两种操作,那么对于并查集的基本几个问题就可以得出解了。

    下面给一道例题:hdu-1232

    并查集的思想在这道题中是十分明显的,对于每一条道路所连接的两个城市,每组两个城市各进行子集判断,只要稍微改一下zhoier函数就行,也是一道比较水的并查集的题:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm> 
    int pre[1000];
    int find(int x)
    {
        return x == pre[x] ? x : x=find(pre[x]); 
    } 
    int main()
    {
       int n,m,p1,p2,i,total,f1,f2;
       while(scanf("%d",&n) && n)         //读入n,如果n为0,结束
       {                                  //刚开始的时候,有n个城镇,一条路都没有 
                                             //那么要修n-1条路才能把它们连起来
           total=n-1;
           //每个点互相独立,自成一个集合,从1编号到n //所以每个点的上级都是自己
           for(i=1;i<=n;i++) 
        { pre[i]=i; } //共有m条路 scanf("%d",&m); while(m--) { //下面这段代码,其实就是zhoier函数,只是稍作改动以适应题目要求 //每读入一条路,看它的端点p1,p2是否已经在一个连通分支里了 scanf("%d %d",&p1,&p2); f1=find(p1); f2=find(p2); //如果是不连通的,那么把这两个分支连起来 //分支的总数就减少了1,还需建的路也就减了1 if(f1!=f2) { pre[f2]=f1; total--; } //如果两点已经连通了,那么这条路只是在图上增加了一个环

          //对连通性没有任何影响,无视掉 }       //最后输出还要修的路条数 printf("%d ",total); } return 0; }
  • 相关阅读:
    Codeforces Round #615 (Div. 3)
    「网络流 24 题」最长 k 可重区间集
    「网络流 24 题」方格取数
    「网络流 24 题」试题库
    debian服务sh启动java,设置开机启动
    debian重置root密码
    uwsgi加载ini文件,nginx重新加载,查看配置文件路劲
    pptpd启动
    android studio java lib不能直接运行
    clipChildren是否限制子控件在该容器所在的范围内
  • 原文地址:https://www.cnblogs.com/Zhoier-Zxy/p/8433130.html
Copyright © 2011-2022 走看看