zoukankan      html  css  js  c++  java
  • bzoj3237 连通图

    题意:在一个无向图上每次删去少量边,问是否还连通?

    标程:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int read()
     4 {
     5     int x=0;char ch=getchar();
     6     while (ch<'0'||ch>'9') ch=getchar();
     7     while ('0'<=ch&&ch<='9') x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
     8     return x;
     9 }
    10 const int N=200005;
    11 int cnt,head[N],n,m,c,k,w,val[N],u[N],v[N],sum,fl,vis[N],base[32],fa[N];
    12 map<int,int> mp;
    13 struct node{int to,next,w;}num[N*2];
    14 void add(int x,int y,int w)
    15 {num[++cnt].to=y;num[cnt].next=head[x];num[cnt].w=w;head[x]=cnt;}
    16 int ins(int x)
    17 {
    18     for (int i=30;i>=0;i--)
    19      if ((x>>i)&1)
    20        if (!base[i]) return base[i]=x,1;
    21        else x^=base[i];
    22     return 0;
    23 } 
    24 void dfs(int x)
    25 {
    26     vis[x]=1;
    27     for (int i=head[x];i;i=num[i].next)
    28     {
    29         if (!vis[num[i].to]) fa[num[i].to]=x,dfs(num[i].to),val[x]^=val[num[i].to];
    30         else if (num[i].to!=fa[x]) val[x]^=num[i].w;
    31     } 
    32 }
    33 int main()
    34 {
    35     srand(2333);
    36     n=read(),m=read();
    37     for (int i=1;i<=m;i++) u[i]=read(),v[i]=read(),w=rand()*131,add(u[i],v[i],w),add(v[i],u[i],w);
    38     dfs(1); k=read();
    39     for (int i=1;i<=n;i++)
    40       if (!vis[i]) {
    41           for (int j=1;j<=k;j++) puts("Disconnected");
    42           return 0;
    43       }
    44     while (k--)
    45     {
    46         c=read();memset(base,0,sizeof(base));fl=1;
    47         for (int i=1;i<=c;i++) 
    48         {
    49             int x=read();
    50             if (fa[u[x]]==v[x]) fl&=ins(val[u[x]]);
    51             else if(fa[v[x]]==u[x]) fl&=ins(val[v[x]]);
    52             else fl&=ins(num[x*2].w);
    53         }
    54         puts(fl?"Connected":"Disconnected");
    55      }
    56     return 0;
    57 } 
    View Code

    题解:随机权值+断开生成子树+线性基/cdq分治

    对每一条边随机一个权值。建一棵生成树,如果要切去一个子树的话必须把子树连到其父亲的根切掉,以及子树中所有的返祖边。

    对于每一个节点保存子树中所有返祖边的异或和。删去的边,如果是非树边,就把其权值扔进线性基;是树边,扔进其保存的子树异或和。

    那么如果某个时刻某权值已经可以在线性基中被线性表示,那么说明Disconnected。

    随机权值这个东西可以用来处理序列上出现奇数次的元素是否恰好有0/1/2个,某条路径是否被全部经过,图联通的判定等等。

    cdq分治

  • 相关阅读:
    Jmeter系列(64)- JMeter JSR223 入门
    Jmeter系列(63)- Beanshell 入门
    Jmeter系列(62)- 详解 JSON 断言
    Jmeter系列(61)- 详解断言持续时间
    Jmeter系列(60)- 详解响应断言
    取球游戏|2012年蓝桥杯B组题解析第十题-fishers
    夺冠概率|2012年蓝桥杯B组题解析第九题-fishers
    密码发生器|2012年蓝桥杯B组题解析第八题-fishers
    放棋子|2012年蓝桥杯B组题解析第七题-fishers
    大数乘法|2012年蓝桥杯B组题解析第六题-fishers
  • 原文地址:https://www.cnblogs.com/Scx117/p/9152242.html
Copyright © 2011-2022 走看看