zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    试试SQLServer 2014的内存优化表
    备份数据库的时候设置 BufferCount 选项不正确导致 out of memory 的情况
    SQLSERVER复制优化之一《改变包大小》
    Tomcat配置域名和虚拟文件夹
    BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
    125 Valid Palindrome
    jquery.lazyload.js实现图片懒载入
    hdu 2176 取石子游戏
    算法练习--十进制 二进制互转
    JavaScript学习10:动态载入脚本和样式
  • 原文地址:https://www.cnblogs.com/cenariusxz/p/4790215.html
Copyright © 2011-2022 走看看