zoukankan      html  css  js  c++  java
  • P5787 二分图 /【模板】线段树分治

    题目描述

    神犇有一个 nn 个节点的图。

    因为神犇是神犇,所以在 kk 时间内有 mm 条边会出现后消失。

    神犇要求出每一时间段内这个图是否是二分图。

    这么简单的问题神犇当然会做了,于是他想考考你。

    原 BZOJ4025。

    输入格式

    第一行三个整数 n,m,kn,m,k。

    接下来 mm 行,每行四个整数 x,y,l,rx,y,l,r,表示有一条连接 x,yx,y 的边在 ll 时刻出现 rr 时刻消失。

    输出格式

    kk 行,第 ii 行一个字符串 Yes 或 No,表示在第 ii 时间段内这个图是否是二分图。

    输入输出样例

    输入 #1
    3 3 3
    1 2 0 2
    2 3 0 3
    1 3 1 2
    
    输出 #1
    Yes
    No
    Yes
    

    说明/提示

    样例说明

    00 时刻,出现两条边 (1,2)(1,2) 和 (2,3)(2,3)。

    第 11 时间段内,这个图是二分图,输出 Yes

    11 时刻,出现一条边 (1,3)(1,3)。

    第 22 时间段内,这个图不是二分图,输出 No

    22 时刻,(1,2)(1,2) 和 (1,3)(1,3) 两条边消失。

    第 33 时间段内,只有一条边 (2,3)(2,3),这个图是二分图,输出 Yes

    数据范围

    n,k = 10^5n,k=105,m = 2 imes 10^5m=2×105。1 le x,y le n1x,yn,0 le l le r le k0lrk。

    注意

    本题设有 hack 数据(Subtask 22),计 00 分,但若没有通过 hack 数据则不算通过本题。

    题解

    线段树分治康复,代码有注释

    代码

     1 //每个操作都有一段存在的时间,将所有操作拆分并覆盖到线段树上。
     2 //DFS线段树,进入节点的时候加入所有这些节点的操作,出节点的时候撤销这些操作,DFS到叶子的时候统计一下答案。 
     3 #include<bits/stdc++.h>
     4 #define N (100009)
     5 using namespace std;
     6 int n,m,k,fa[N<<1],dep[N<<1],top;
     7 vector<pair<int,int> > e[N<<2];
     8 pair<int,int>st[N<<1];
     9 void Update(int now,int l,int r,int l1,int r1,int x,int y) {
    10     if (l>r1 || r<l1) return;
    11     if (l1<=l && r<=r1) {
    12         e[now].push_back(make_pair(x,y));
    13         return;
    14     }
    15     int mid=(l+r)>>1;
    16     Update(now<<1,l,mid,l1,r1,x,y);
    17     Update(now<<1|1,mid+1,r,l1,r1,x,y);
    18 }
    19 int Find(int x) {
    20     return x==fa[x]?x:Find(fa[x]);
    21 }
    22 void Merge(int fx,int fy) {
    23     if (dep[fx]>dep[fy]) swap(fx,fy);
    24     fa[fx]=fy; dep[fy]+=(dep[fx]==dep[fy]);
    25     st[++top]=make_pair(fx,fy);
    26 }//按秩合并并查集,用栈存历史操作,方便撤销
    27 void DFS(int now,int l,int r,int flag) {
    28     int mid=(l+r)>>1, tmp=top;
    29     for (int i=0; i<e[now].size(); ++i) {
    30         int x=e[now][i].first, y=e[now][i].second;
    31         int fx=Find(x), fy=Find(y), fx_=Find(x+n), fy_=Find(y+n);
    32         if (fx==fy) {
    33             flag=0;
    34             break;
    35         }
    36         Merge(fx,fy_); Merge(fy,fx_);
    37     }
    38     if (l<r) DFS(now<<1,l,mid,flag), DFS(now<<1|1,mid+1,r,flag);
    39     else puts(flag?"Yes":"No");
    40     for (int i=top; i>tmp; --i) {
    41         int fx=st[i].first, fy=st[i].second;
    42         fa[fx]=fx; dep[fy]-=(dep[fx]+1==dep[fy]);
    43     }
    44     top=tmp;
    45 }//并查集判断二分图,加入边(x,y)时若x和y在一个集合就不能构成二分图,否则能构成且合并(x,y'),(x',y)
    46 int main() {
    47     cin>>n>>m>>k;
    48     for (int i=1; i<=2*n; ++i) fa[i]=i, dep[i]=1;
    49     for (int i=1; i<=m; ++i) {
    50         int x,y,l,r;
    51         cin>>x>>y>>l>>r;
    52         Update(1,0,k-1,l,r-1,x,y);
    53     }
    54     DFS(1,0,k-1,1);
    55 }
  • 相关阅读:
    fzuoj Problem 2177 ytaaa
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Capture the Flag
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Team Formation
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Beauty of Array
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Lunch Time
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Convert QWERTY to Dvorak
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest May Day Holiday
    zoj The 12th Zhejiang Provincial Collegiate Programming Contest Demacia of the Ancients
    zjuoj The 12th Zhejiang Provincial Collegiate Programming Contest Ace of Aces
    csuoj 1335: 高桥和低桥
  • 原文地址:https://www.cnblogs.com/refun/p/15066470.html
Copyright © 2011-2022 走看看