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
  • 相关阅读:
    viewpager中彻底性动态添加、删除Fragment
    Android仿微信界面--使用Fragment实现(慕课网笔记)
    Android progressBar 自定义
    Android 使用PopupWindow实现弹出菜单
    android手机上安装apk时出现解析包错误的一个解决办法
    设计模式 单例模式
    android 自定义AlertDialog
    android listview异步加载图片
    又优化了一下 Android ListView 异步加载图片
    Hadoop概念学习系列之谈谈RPC(三十三)
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3834913.html
Copyright © 2011-2022 走看看