• 【BZOJ4025】二分图


    传送门

    Description

    神犇有一个n个节点的图。因为神犇是神犇,所以在T时间内一些边会出现后消失。神犇要求出每一时间段内这个图是否是二分图。这么简单的问题神犇当然会做了,于是他想考考你。

    Input

    输入数据的第一行是三个整数n,m,T。
    第2行到第m+1行,每行4个整数u,v,start,end。第i+1行的四个整数表示第i条边连接u,v两个点,这条边在start时刻出现,在第end时刻消失。

    Output

    输出包含T行。在第i行中,如果第i时间段内这个图是二分图,那么输出“Yes”,否则输出“No”,不含引号。

    【题解思路】

    线段树分治+并查集启发式合并

    与【BZOJ3237】联通块做法类似

    下面介绍线段树分治:

    (时间线段树)有关的题以后会补充上来的

    支持修改和查询,修改只在一段时间内生效,顺序可以交换,可撤销但不可删除。 对时间建立一棵线段树。 每个修改生效的时间在线段树上对应O(logn)个区间,在这些区间插入这个修改。 dfs这棵线段树,进入一个节点时进行这上面的修改,离开时撤销。 dfs到叶子时,正好进行了这个时间点生效的所有修改。

    需要维护的是每个点在联通块中的奇偶性。

    【code】

    #include<bits/stdc++.h> 
    using namespace std;
    #define ll long long
    #define ull unsigned long long
    #define rep(k,i,j) for(int k = i;k <= j; ++k)
    #define FOR(k,i,j) for(int k = i;k >= j; --k)
    inline int read(){
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=getchar();}
        return x*f; 
    }
    const int mxn = 1e5+5;
    struct pr{int u,v;};
    vector<pr> tree[mxn<<2];
    bool ans[mxn];
    inline void build(int pos,int lp,int rp,int l,int r,pr range){
        if(l<=lp&&rp<=r){
            tree[pos].push_back(range);
            return;
        }
        int m = lp+rp >>1;
        if(l<=m) build(pos<<1,lp,m,l,r,range);
        if(r>m) build(pos<<1|1,m+1,rp,l,r,range);
    }
    int f[mxn],sz[mxn],dis[mxn];
    inline int getf(int x){
        if(x==f[x]) return x;
        return f[x] = getf(f[x]);
    }
    inline int getd(int x){
        int d = 0;
        while(x!=f[x])
            d ^= dis[x],x = f[x];//奇数次or偶数次 
        return d;
    }
    inline void wor(int pos/*time*/,int l,int r){
        vector<pr>opt;
        int m = l+r >>1;
        bool flag = 0;
        int sz1 = tree[pos].size();
        for(int i = 0;i < sz1; ++i){
            int x = tree[pos][i].u,y = tree[pos][i].v;
            int fx = getf(x),fy = getf(y);
            if(fx==fy){
                if(!(getd(x)^getd(y))){
                    flag = 1;
                    break;    
                }//没有距离 
            }else{
                if(sz[fx]>sz[fy]) swap(fx,fy),swap(x,y);
                sz[y] += sz[x];
                dis[fx] ^= dis[x]^dis[y]^1;
                f[fx] = fy;
                opt.push_back((pr){fx,fy});
            }
        }
        if(!flag){
            if(l==r) ans[l] = true;
            else wor(pos<<1,l,m),wor(pos<<1|1,m+1,r);
        }
        int sz2 = opt.size();
        for(int i = sz2-1; i > 0; --i){
            int x = opt[i].u,y = opt[i].v;
            sz[y] -= sz[x];
            dis[x] = 0;
            f[x] = x;
        }
    }
    int n,m,T;
    int main(){
        n = read(),m = read(),T = read();
        rep(i,1,m){
            int u = read(),v = read();
            int l = read(),r = read();
            if(l<r) build(1,1,T,l+1,r,(pr){u,v});
        }
        rep(i,1,n) f[i] = i,sz[i] = 1;
        wor(1,1,T);
        rep(i,1,T) puts(ans[i]?"Yes":"No");
        return 0;
    }
    View Code
    G102的孤儿们都要好好的啊。
  • 相关阅读:
    VS2008中应用.NET 4.0中的代码契约
    生日快乐
    Did you know…How to maintain scrollposition after post back? z
    微软正式发布SQL Server 2008
    想要注册一个写日记用的博客(选好了)
    SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY的区别(比较) z
    Microsoft Visual Studio 2010 and the .NET Framework 4.0 CTP下载
    mysql
    如何用iframe代码显示调用网页的指定部分
    文件夹权限
  • 原文地址:https://www.cnblogs.com/ve-2021/p/10397466.html
Copyright © 2020-2023  润新知