• [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
  • 相关阅读:
    数据结构(一)线性表单链表试题
    虚拟研讨会:如何设计好的RESTful API?
    如何生成RestFul Api文档
    webstorm 10 设置文件的默认编码
    HAML学习
    Nodejs初阶之express
    RESTful API 简书
    解读Nodejs多核处理模块cluster
    Nginx做NodeJS应用负载均衡配置实例
    拿nodejs快速搭建简单Oauth认证和restful API server攻略
  • 原文地址:https://www.cnblogs.com/wls001/p/10037697.html
Copyright © 2020-2023  润新知