zoukankan      html  css  js  c++  java
  • BZOJ3237: [Ahoi2013]连通图

    $n leq 1e5,m leq 2e5$的无向图,每次问:删若干$(leq 15)$条边图是否连通。

    3563和3569就不写了。。三倍

    建个图的dfs树,非树边带随机权,点权为从其出发的所有非树边权异或和,树边的权值为其子树内点权异或和。如此当一棵子树被完全切下来时,会有一些选中的边权异或和为0.

    异或和为0时,一定会选中树边,选中的树边的子树会与外层点脱离。

    因此线性基判断即可。

     1 //#include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 //#include<time.h>
     5 //#include<complex>
     6 //#include<set>
     7 //#include<queue>
     8 #include<algorithm>
     9 #include<stdlib.h>
    10 using namespace std;
    11 
    12 #define LL long long
    13 int qread()
    14 {
    15     char c; int s=0; while ((c=getchar())<'0' || c>'9');
    16     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s;
    17 }
    18 
    19 //Pay attention to '-' , LL and double of qread!!!!
    20 
    21 int n,m,lq;
    22 #define maxn 100011
    23 #define maxm 400011
    24 struct Edge{int to,next;}edge[maxm]; int first[maxn],ve[maxm],le=2;
    25 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
    26 void insert(int x,int y) {in(x,y); in(y,x);}
    27 
    28 int Rand() {return (rand()<<15)+rand()+1;}
    29 
    30 struct JI
    31 {
    32     int a[33];
    33     void clear() {memset(a,0,sizeof(a));}
    34     bool insert(int v)
    35     {
    36         for (int i=30;~i && v;i--) if ((v>>i)&1)
    37         {
    38             if (!a[i]) {a[i]=v; return 1;}
    39             v^=a[i];
    40         }
    41         return 0;
    42     }
    43 }ji;
    44 
    45 int val[maxn],dep[maxn]; bool vis[maxn];
    46 void dfs(int x,int fa)
    47 {
    48     vis[x]=1;
    49     for (int i=first[x];i;i=edge[i].next)
    50     {
    51         Edge &e=edge[i]; if (e.to==fa) continue;
    52         if (vis[e.to])
    53         {
    54             if (!ve[i]) ve[i]=ve[i^1]=Rand(),val[e.to]^=ve[i],val[x]^=ve[i];
    55         }
    56         else dep[e.to]=dep[x]+1,dfs(e.to,x),val[x]^=val[e.to];
    57     }
    58 //    cout<<x<<' '<<val[x]<<' '<<dep[x]<<endl;
    59 }
    60 
    61 int main()
    62 {
    63     srand(19260817);
    64     n=qread(); m=qread();
    65     for (int i=1;i<=m;i++) insert(qread(),qread());
    66     dfs(1,0);
    67 //    for (int i=2;i<le;i+=2) cout<<ve[i]<<' ';cout<<endl;
    68     lq=qread();
    69     for (int i=1,x,y;i<=lq;i++)
    70     {
    71         ji.clear();
    72         x=qread();
    73         bool flag=1;
    74         for (int j=1;j<=x;j++)
    75         {
    76             y=qread();
    77             if (flag)
    78             {
    79                 if (ve[y<<1]) flag=ji.insert(ve[y<<1]);
    80                 else flag=ji.insert(val[dep[edge[y<<1].to]>dep[edge[(y<<1)|1].to]?
    81                 edge[y<<1].to:edge[(y<<1)|1].to]);
    82             }
    83         }
    84         puts(flag?"Connected":"Disconnected");
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    状态同步和帧同步
    SVN和Git的使用
    客户端知识点
    客户端性能优化
    H5游戏开发面试经验
    2.0 pomelo-treasure官方demo的使用
    1.0 pomelo环境的搭建和部署
    python 网络编程
    冒泡排序
    面向对象-反射和元类
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8926015.html
Copyright © 2011-2022 走看看