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 }
  • 相关阅读:
    ubuntu安装gnome桌面,ubuntu系统16升级到18
    重置root密码
    shell中tr的用法
    ubuntu14.04安装zabbix
    TTTTTTTTTTTTTT poj 1127 Jack Straws 线段相交+并查集
    TTTTTTTTTTTTT poj 3057 Evacuation 二分图匹配+bfs
    hdu 1208 Ignatius and the Princess III 划分数,dp
    Poj 3057 未AC http://poj.org/showsource?solution_id=15175171
    poj 3662 Telephone Lines dijkstra+二分搜索
    poj 3684 Physics Experiment 弹性碰撞
  • 原文地址:https://www.cnblogs.com/refun/p/15066470.html
Copyright © 2011-2022 走看看