zoukankan      html  css  js  c++  java
  • [BZOJ4025] 二分图 LCT/(线段树分治+并查集)

    4025: 二分图

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 2667  Solved: 989
    [Submit][Status][Discuss]

    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”,不含引号。

    Sample Input

    3 3 3
    1 2 0 2
    2 3 0 3
    1 3 1 2

    Sample Output

    Yes
    No
    Yes

    HINT

    样例说明:

    0时刻,出现两条边1-2和2-3。

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

    1时刻,出现一条边1-3。

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

    2时刻,1-2和1-3两条边消失。

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

     

    数据范围:

    n<=100000,m<=200000,T<=100000,1<=u,v<=n,0<=start<=end<=T。

     

    Source

    LCT做法

     其实就是求是否有奇环。先求出最小生成树,随后根据非树边两点间的距离得出是否有奇环。

    lct维护以边消失时间为权值的最大生成树。这样可以保证所有已经进入集合的非树边都不会从集合中出来再次成为树边。
    从小到达枚举时间进行加边和删边。
    加边判奇环,更新最大生成树和集合.
    删边如果是最大生成树里的边就在lct中删掉。否则仅在集合中删掉即可。

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cmath>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<cstring>
      7 #define maxn 400001
      8 using namespace std;
      9 inline int read() {
     10     char ch=getchar();int x=0,f=1;
     11     for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
     12     for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
     13     return x*f;
     14 }
     15 int n,m,T,ont[maxn*2],jh[maxn*2],tot,val[maxn*2];
     16 struct Edge {
     17     int to[maxn*4],nxt[maxn*4],head[maxn*2],cnt;
     18     Edge(){memset(head,-1,sizeof(head));cnt=0;}
     19     void add(int u,int v) {to[cnt]=v;nxt[cnt]=head[u];head[u]=cnt++;}
     20 }e1,e2;
     21 struct ASK {int u,v,w;}a[maxn*2];
     22 struct LCT {
     23     struct Data {
     24         int son[2],sz,fa,rev,mn;
     25     }t[maxn*2];
     26     bool isrt(int x) {return t[t[x].fa].son[0]!=x&&t[t[x].fa].son[1]!=x;}
     27     void pushdown(int x) {
     28         if(t[x].rev) {
     29             swap(t[x].son[0],t[x].son[1]);
     30             t[t[x].son[0]].rev^=1;t[t[x].son[1]].rev^=1;
     31             t[x].rev=0;
     32         }
     33     }
     34     void pushup(int x) {
     35         t[x].sz=t[t[x].son[0]].sz+t[t[x].son[1]].sz+(x>n);
     36         t[x].mn=x;
     37         if(val[t[t[x].son[0]].mn]<val[t[x].mn]) t[x].mn=t[t[x].son[0]].mn;
     38         if(val[t[t[x].son[1]].mn]<val[t[x].mn]) t[x].mn=t[t[x].son[1]].mn;
     39     }
     40     void rotate(int x) {
     41         int y=t[x].fa,z=t[y].fa;
     42         bool l=(t[y].son[1]==x),r=l^1;
     43         if(!isrt(y)) t[z].son[t[z].son[1]==y]=x;
     44         t[x].fa=z;t[y].fa=x;t[t[x].son[r]].fa=y;
     45         t[y].son[l]=t[x].son[r];t[x].son[r]=y;
     46         pushup(y);pushup(x);
     47     }
     48     void push(int x) {
     49         if(!isrt(x)) push(t[x].fa);
     50         pushdown(x);
     51     }
     52     void splay(int x) {
     53         push(x);
     54         while(!isrt(x)) {
     55             int y=t[x].fa,z=t[y].fa;
     56             if(!isrt(y)) {
     57                 if(t[y].son[0]==x^t[z].son[0]==y) rotate(x);
     58                 else rotate(y);
     59             }
     60             rotate(x);
     61         }
     62     }
     63     void access(int x) {for(int pre=0;x;pre=x,x=t[x].fa) {splay(x),t[x].son[1]=pre;pushup(x);}}
     64     void makert(int x) {access(x);splay(x);t[x].rev^=1;}
     65     void link(int x,int y) {makert(x);t[x].fa=y;}
     66     void cut(int x,int y) {makert(x);access(y);splay(y);t[y].son[0]=t[x].fa=0;}
     67     int find(int x) {access(x);splay(x);while(t[x].son[0]) x=t[x].son[0];return x;}
     68 }lct;
     69 void insert(int x,int u,int v,int w) {
     70     if(u==v) {jh[x]=1;tot++;return;}
     71     if(lct.find(u)!=lct.find(v)) {
     72         
     73         ont[x]=1;lct.link(u,n+x);lct.link(v,n+x);
     74     }
     75     else {
     76         lct.makert(v);lct.access(u);lct.splay(u);int tmp=lct.t[u].mn-n;
     77         if(a[tmp].w<a[x].w) {
     78             if(!(lct.t[u].sz&1)) {jh[tmp]=1;tot++;}
     79             lct.cut(a[tmp].u,tmp+n);lct.cut(a[tmp].v,tmp+n);
     80             lct.link(u,n+x);lct.link(v,n+x);
     81             ont[tmp]=0;ont[x]=1;
     82         }
     83         else {
     84             if(!(lct.t[u].sz&1)) {jh[x]=1;tot++;}
     85         }
     86     }
     87 }
     88 void del(int x,int u,int v,int w) {
     89     if(ont[x]) {lct.cut(u,x+n);lct.cut(v,x+n);}
     90     else if(jh[x]) tot--;
     91 }
     92 int main() {
     93     n=read(),m=read(),T=read();
     94     memset(val,27,sizeof(val));
     95     for(int i=1;i<=n;i++) lct.t[i].mn=i;
     96     for(int i=1;i<=m;i++) {
     97         a[i].u=read(),a[i].v=read();int s=read(),t=read();
     98         e1.add(s,i);e2.add(t,i);a[i].w=t;lct.t[n+i].sz=1;lct.t[n+i].mn=n+i;val[n+i]=t;
     99     }
    100     for(int i=0;i<T;i++) {
    101         for(int j=e1.head[i];j>=0;j=e1.nxt[j]) {
    102             int to=e1.to[j];
    103             insert(to,a[to].u,a[to].v,a[to].w);
    104         }
    105         for(int j=e2.head[i];j>=0;j=e2.nxt[j]) {
    106             int to=e2.to[j];
    107             del(to,a[to].u,a[to].v,a[to].w);
    108         }
    109         if(!tot) printf("Yes
    ");
    110         else printf("No
    ");
    111     }
    112     return 0;
    113 }
    114 /*
    115 45365
    116 57727
    117 */
    View Code
  • 相关阅读:
    nginx.conf文件
    本地apache 可以正常访问,lnmp服务器访问404错误
    PHP网站从Apache转移到Nginx后产生404错误的原因和解决办法
    CGI,FAST-CGI,PHP-FPM的区别
    Lnmp修改php.ini配置
    APACHE服务器出现No input file specified.的完美解决方案
    EXCEL常用函数详解
    chrome extensions
    C++使用OLE高速读写EXCEL的源码
    C++读写EXCEL文件OLE,java读写excel文件POI 对比
  • 原文地址:https://www.cnblogs.com/wls001/p/10037697.html
Copyright © 2011-2022 走看看