• poj1733 带权并查集


    题意:有一个 0/1 数列,现在有n组询问和回答,表示某个区间内有奇数或者偶数个1,问到前多少个都没有逻辑错误,而下一个就不满足

    可以定奇数为 1 偶数为 0作为每个元素的权值,表示它与它的祖先元素的差距,这样通过 mod2 可以直接表示两奇或两偶都得偶,奇偶得奇,然后就是对前序1的个数和做并查集的操作,注意对于一个区间[a,b],合并的两个元素是 a-1 和 b 。直到找到错误就可以了。由于区间太大,可以离散化各个需要合并的元素,再离线操作并查集。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<map>
     4 using namespace std;
     5 
     6 int fa[10005],n,m,num[10005],a[5005],b[5005],v[5005];
     7 char s[10];
     8 
     9 void init(){
    10     for(int i=0;i<=10000;i++)fa[i]=i;
    11     memset(num,0,sizeof(num));
    12 }
    13 
    14 int find(int x){
    15     int r=x,c=0,t1,t2;
    16     while(r!=fa[r]){
    17         c+=num[r];
    18         r=fa[r];
    19     }
    20     while(x!=r){
    21         t1=fa[x];
    22         t2=c-num[x];
    23         fa[x]=r;
    24         num[x]=c%2;
    25         x=t1;
    26         c=t2;
    27     }
    28     return r;
    29 }
    30 
    31 int main(){
    32     scanf("%d%d",&n,&m);
    33     init();
    34     int i,cnt=0,ans=0;
    35     map<int,int>M;
    36     for(i=1;i<=m;i++){
    37         scanf("%d%d%s",&a[i],&b[i],s);
    38         a[i]--;
    39         if(s[0]=='e')v[i]=0;
    40         else v[i]=1;
    41         if(!M[a[i]])M[a[i]]=++cnt;
    42         if(!M[b[i]])M[b[i]]=++cnt;
    43     }
    44     bool f=1;
    45     for(i=1;i<=m;i++){
    46         int x=find(M[a[i]]),y=find(M[b[i]]);
    47         if(x!=y){
    48             num[x]=((num[M[b[i]]]+v[i]-num[M[a[i]]])%2+2)%2;
    49             fa[x]=y;
    50             if(f)ans++;
    51         }
    52         else{
    53             if(f){
    54                 if(!v[i]&&num[M[a[i]]]==num[M[b[i]]])ans++;
    55                 else if(v[i]&&num[M[a[i]]]!=num[M[b[i]]])ans++;
    56                 else f=0;
    57             }
    58         }
    59     }/*
    60     for(i=1;i<=m;i++){
    61         printf("%d %d %d
    ",M[a[i]],M[b[i]],v[i]);
    62     }
    63     for(i=1;i<=cnt;i++){
    64         printf("%d %d %d
    ",i,fa[i],num[i]);
    65     }*/
    66     printf("%d
    ",ans);
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    深入理解 JavaScript(五)
    深入理解 JavaScript(四)
    深入理解 JavaScript(三)
    opecv官网接口查询
    一个python-opencv博客
    Python中range和xrange的区别
    【转载】opencv 二值化函数——cv2.threshold
    python-opencv中的cv2.inRange函数
    anaconda conda install wxpython4 安装包 python3环境(GUI)
    python之assert
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4790215.html
Copyright © 2020-2023  润新知