• 种类并查集


      一般的并查集是维护属于同一种类的元素,对于属于不同种类的元素之间的关系没有记录。种类并查集就是同一集合中的元素是已经确定关系的(是否属于同一种类),然后加一个group数组,记录一下孩子和父亲是否属于同一种类,递推稍稍改一下就可以了。

    poj1703:http://poj.org/problem?id=1703

    题目大意:有n个罪犯,两个帮派,已知其中若干对两者属于不同帮派,求给定的罪犯是否属于同一帮派。

    需要注意,给的两个罪犯可能已经在同一个集合里了,需要处理一下,不然就无限递归了。。。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 const int maxn=1e5+5;
     6 int p[maxn],group[maxn],n,m;
     7 int Find(int x){
     8     if(p[x]==x)return x;
     9     int t=Find(p[x]);
    10     group[x]=group[x]==group[p[x]]?1:0;
    11     return p[x]=t;
    12 }
    13 void Unit(int a,int b){
    14     int x=Find(a),y=Find(b);
    15     if(x==y)return;
    16     p[x]=b;
    17     group[x]=1^group[a];
    18 }
    19 int Is_same(int a,int b){
    20     int x=Find(a),y=Find(b);
    21     if(x!=y)return -1;
    22     return group[a]==group[b];
    23 }
    24 int main(){
    25     int t,a,b;
    26     char c;
    27     scanf("%d",&t);
    28     while(t--){
    29         scanf("
    %d%d",&n,&m);
    30         for(int i=0;i<n;i++){p[i]=i;group[i]=1;}
    31         for(int i=0;i<m;i++){
    32             scanf("
    %c%d%d",&c,&a,&b);
    33             a--;b--;
    34             if(c=='D'){
    35                 Unit(a,b);
    36             }else{
    37                 int t=Is_same(a,b);
    38                 if(t==-1)printf("Not sure yet.
    ");
    39                 else if(t==0)printf("In different gangs.
    ");
    40                 else if(t==1)printf("In the same gang.
    ");
    41             }
    42         }
    43     }
    44     return 0;
    45 }

    51nod 1204 Parity

    分析:记前k个的和的奇偶性为f[k],若[a,b]和为偶数,则f[a]==f[b],否则f[a]!=f[b],然后用种类并查集维护一下就可以了。

     1 #include<iostream>
     2 #include<string>
     3 using namespace std;
     4 const int maxn=100005;
     5 int p[maxn],group[maxn],n,q;
     6 int Find(int x){
     7     if(p[x]==x)return x;
     8     Find(p[x]);
     9     group[x]=group[p[x]]==group[x]?1:0;
    10     p[x]=Find(p[x]);
    11     return p[x];
    12 }
    13 int main(){
    14     cin>>n>>q;
    15     for(int i=0;i<=n;i++){p[i]=i;group[i]=1;}
    16     int a,b,ans=-1;
    17     char s[10];
    18     for(int i=0;i<q;i++){
    19         cin>>a>>b>>s;
    20         int x=Find(a-1),y=Find(b);
    21         if(s[0]=='e'){
    22             if(x==y&&group[a-1]!=group[b]&&ans==-1)
    23                 ans=i+1;
    24             if(x!=y){
    25                 p[x]=y;
    26                 group[x]=group[a-1]==group[b]?1:0;
    27             }
    28         }else{
    29             if(x==y&&group[a-1]==group[b]&&ans==-1)
    30                 ans=i+1;
    31             if(x!=y){
    32                 p[x]=y;
    33                 group[x]=group[a-1]==group[b]?0:1;
    34             }
    35         }
    36     }
    37     cout<<ans<<endl;
    38     return 0;
    39 }
  • 相关阅读:
    20174311 唐嘉 《网络对抗技术》Exp2 后门原理与实践
    20174311 唐嘉《网络对抗技术》Exp1 PC平台逆向破解
    20174304王天政《网络对抗技术》Exp9 Web安全基础
    20174304王天政《网络对抗技术》Exp8 Web基础
    20174304王天政《网络对抗技术》Exp7 网络欺诈防范
    20174304王天政《网络对抗技术》Exp6 MSF基础应用
    20174304王天政《网络对抗技术》Exp5 信息搜集与漏洞扫描
    20174304王天政《网络对抗技术》Exp4 恶意代码分析
    20174304王天政《网络对抗技术》Exp3免杀原理与实践
    20174304王天政《网络对抗技术》Exp2-后门原理与实践
  • 原文地址:https://www.cnblogs.com/7391-KID/p/7062363.html
Copyright © 2020-2023  润新知