zoukankan      html  css  js  c++  java
  • bzoj3569 DZY Loves Chinese II & bzoj3237 [AHOI2013] 连通图

    给一个无向连通图,多次询问,每次询问给 k 条边,问删除这 k 条边后图的连通性,对于 bzoj3237 可以离线,对于 bzoj3569 强制在线

    $n,m,q leq 500000,k leq 15$

    sol:

    离线的话很好做,xjb 分治就行了,大概就是 bzoj4025 二分图那题改一改,用一个带权并查集维护连通块大小,当然删除时间最大生成树也是可以做的

    在线的话,我们需要一些神仙操作

    首先,随便搞出这个图的一棵生成树,对于每个非树边,我们给它随机一个权值

    然后对于每条树边,我们让它的权值为覆盖它的所有非树边异或和

    我们发现图不连通当且仅当一条树边和所有覆盖它的非树边都被删除

    因为树边权值 xor 所有覆盖它的非树边权值异或和 = 0

    于是问题变成了:“给你一个边集,判断是否有一个子集异或和为 0 ”

    这个就要用到线性基的那一套理论

    我们知道求线性基的时候可以求出一组极大线性无关集

    看这个线性无关集大小是否为 k 即可

    求线性基可以高斯消元

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    inline int read()
    {
        int x = 0,f = 1;char ch = getchar();
        for(;!isdigit(ch);ch = getchar())if(ch == '-') f = -f;
        for(;isdigit(ch);ch = getchar())x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 500010;
    int n,m;
    int first[maxn],to[maxn << 1],nx[maxn << 1],val[maxn << 1],cnt = 1;
    inline void add(int u,int v)
    {
        to[++cnt] = v;
        nx[cnt] = first[u];
        first[u] = cnt;
    }
    inline void ins(int u,int v){add(u,v);add(v,u);}
    int bin[35],vis[maxn],v[maxn];
    int lastans,a[50];
    inline void maketree(int x,int fa)
    {
        vis[x] = 1;
        for(int i=first[x];i;i=nx[i])
        {
            if(to[i] == fa)continue;
            if(!vis[to[i]])maketree(to[i],x);
            else if(!val[i >> 1])
            {
                val[i >> 1] = rand();
                v[x] ^= val[i >> 1];
                v[to[i]] ^= val[i >> 1];
            }
        }
    }
    inline void dfs(int x)
    {
        vis[x] = 1;
        for(int i=first[x];i;i=nx[i])
        {
            if(vis[to[i]])continue;
            dfs(to[i]);v[x] ^= v[to[i]];
            val[i >> 1] = v[to[i]];
        }
    }
    int Gauss_Jordan(int n)
    {
        int now = 1;
        for(int i=30;i>=0;i--)
        {
            int j = now;
            while(j <= n &&!(a[j] & (1 << (i - 1)))) j++;
            if(j == n+1) continue;
            if(j != now) swap(a[now],a[j]);
            for(int k=1;k<=n;k++)
                if(k != now && (a[k] & (1 << (i - 1)))) a[k] ^= a[now];
            now++;
        }
        now--;
        return now;
    }
    int main()
    {
        srand((unsigned long long)new char);
        n = read(),m = read();
        for(int i=1;i<=m;i++)
        {
            int u = read(),v = read();
            ins(u,v);
        }maketree(1,0);
        memset(vis,0,sizeof(vis));
        dfs(1);int q = read();
        while(q--)
        {
            int k = read(),top = 0;
            while(k--)a[++top] = val[read() ^ lastans];
            int res = Gauss_Jordan(top);
            if(res < top)puts("Disconnected");
            else lastans++,puts("Connected");
        }
    }
    View Code
  • 相关阅读:
    Android_listview设置每条信息的间距
    Android实现ListView或GridView首行/尾行距离屏幕边缘距离
    实现类似微信的延迟加载的Fragment——LazyFragment
    struts2的Action该方法不能去
    (工具)source insight高速增加时间代码
    猫学习IOS(十五)UI以前的热的打砖块游戏
    java语言内部类和匿名内部类
    JVM截至多少线程可以创建: unable to create new native thread
    linux下一个Oracle11g RAC建立(八)
    转基因小麦--主题在农业科技的最前沿
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10058365.html
Copyright © 2011-2022 走看看