zoukankan      html  css  js  c++  java
  • POJ 1182

    http://poj.org/problem?id=1182

    带权并查集第一题,三种类型的生物,分别加入三个集合,题解见注释

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std ;
    #define MAX_N 150005
    int par[MAX_N] ;//父亲 
    int rank[MAX_N] ;//树的高度 
    void INIT(int n)
    {
        for(int i=0 ;i<n ;i++){
            par[i]=i ;
            rank[i]=0 ;
        }
    }
    int find(int x)
    {
        if(par[x]==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(rank[x]<rank[y]){
            par[x]=y ;
        }
        else{
            par[y]=x ;
            if(rank[x]==rank[y])rank[x]++ ;
        }
    }
    bool same(int x,int y)
    {
        return find(x)==find(y) ;
    }
    int n,k,T[100005],X[100005],Y[100005] ;
    void solve()
    {
        //x x+n x+2*n 分别代表A B C类 
        //x y属于同一类 合并x-A和y-A x-B和y-B x-C和y-C
        //x吃y 合并x-A和y-B x-B和y-C x-C和y-A 
        //提前判断矛盾 
        INIT(3*n) ;
        int ans=0 ;
        for(int i=0 ;i<k ;i++)
        {
            int t=T[i] ;
            int x=X[i]-1,y=Y[i]-1 ;
            if(x<0 || x>=n || y<0 || y>=n)
            {
                ans++ ;
                continue ;
            }
            if(t==1)
            {
                if(same(x,y+n) || same(x,y+2*n))
                {
                    ans++ ;
                }
                else
                {
                    unite(x,y) ;
                    unite(x+n,y+n) ;
                    unite(x+2*n,y+2*n) ;
                }
            }
            else
            {
                if(same(x,y) || same(x,y+2*n))
                {
                    ans++ ;
                }
                else
                {
                    unite(x,y+n) ;
                    unite(x+n,y+2*n) ;
                    unite(x+2*n,y) ;
                }
            }
        }
        printf("%d
    ",ans) ;
    }
    int main()
    {
        scanf("%d%d",&n,&k) ;
        for(int i=0 ;i<k ;i++)
            scanf("%d%d%d",&T[i],&X[i],&Y[i]) ;
        solve() ;
        return 0 ;
    }
    View Code

     常规带权并查集解法

    #include <iostream>
    #include <cstdio>
    #include <set>
    #include <cmath>
    using namespace std ;
    #define MAX_N 50005
    int par[MAX_N] ;//父亲 
    int rank[MAX_N] ;//树的高度 
    void INIT(int n)
    {
        for(int i=0 ;i<n ;i++){
            par[i]=i ;
            rank[i]=0 ;
        }
    }
    int find(int x)
    {
        if(par[x]==x){
            return x ;
        }
        else{
            int temp=par[x] ;
            par[x]=find(par[x]) ;
            rank[x]=(rank[x]+rank[temp])%3 ;
            return par[x] ;
        }
    }
    void unite(int x,int y,int d)
    {
        int xp=find(x) ;
        int yp=find(y) ;
        par[xp]=yp ;
        rank[xp]=(rank[y]-rank[x]+3+d)%3 ;
    }
    bool same(int x,int y)
    {
        return find(x)==find(y) ;
    }
    int n,k,T[100005],X[100005],Y[100005] ;
    void solve()
    {
        INIT(n) ;
        int ans=0 ;
        for(int i=0 ;i<k ;i++)
        {
            int t=T[i] ;
            int x=X[i]-1,y=Y[i]-1 ;
            if(x<0 || x>=n || y<0 || y>=n)
            {
                ans++ ;
                continue ;
            }
            int xp=find(x) ;
            int yp=find(y) ;
            if(xp==yp)
            {
                if((rank[x]-rank[y]+3)%3!=t-1)
                    ans++ ;          
            }
            else
            {
                unite(x,y,t-1) ;
            }
        }
        printf("%d
    ",ans) ;
    }
    int main()
    {
        scanf("%d%d",&n,&k) ;
        for(int i=0 ;i<k ;i++)
            scanf("%d%d%d",&T[i],&X[i],&Y[i]) ;
        solve() ;
        return 0 ;
    }
    View Code
  • 相关阅读:
    DHCP三种配置
    Linux-9引导过程与服务控制
    Linux系统管理10-进程和计划任务管理
    Linux系统管理11-系统安全及应用
    Linux系统管理12-Linux文件系统与日志
    ---01--Lin网络基础设置
    服务器RAID及磁盘配额的配置
    Linux常见故障及修复方法
    作业5
    104 权限 sudo 解压缩
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3834913.html
Copyright © 2011-2022 走看看