zoukankan      html  css  js  c++  java
  • BZOJ4025: 二分图(LCT)

    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

    解题思路:

    LCT维护图的连通性很好的一道题。

    发现如果是树那么一定可以,如果奇数环一定不是。

    离线一下,然后维护一颗树中最早被删除的点。

    维护最后一条边(可以用数组存)

    最后判一下就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 using std::swap;
      9 using std::sort;
     10 const int E=100005;
     11 struct trnt{
     12     int ch[2];
     13     int fa;
     14     int lzt;
     15     int val;
     16     int mnp;
     17     int mn;
     18     int sum;
     19     int tip;
     20     bool anc;
     21 }tr[1000000];
     22 struct ent{
     23     int f,t,dl;
     24 }e[1000000];
     25 struct Event{
     26     bool cmd;
     27     int f,t,tpc;
     28     int no;
     29 }ev[1000000];
     30 int n,m,T;
     31 int num;
     32 int cnt;
     33 bool onr[1000000];
     34 bool odd[1000000];
     35 bool whc(int spc)
     36 {
     37     return tr[tr[spc].fa].rs==spc;
     38 }
     39 void pushup(int spc)
     40 {
     41     tr[spc].sum=tr[spc].val;
     42     tr[spc].mn=tr[spc].tip;
     43     tr[spc].mnp=spc;
     44     if(lll)
     45     {
     46         tr[spc].sum+=tr[lll].sum;
     47         if(tr[spc].mn>tr[lll].mn)
     48         {
     49             tr[spc].mn=tr[lll].mn;
     50             tr[spc].mnp=tr[lll].mnp;
     51         }
     52     }
     53     if(rrr)
     54     {
     55         tr[spc].sum+=tr[rrr].sum;
     56         if(tr[spc].mn>tr[rrr].mn)
     57         {
     58             tr[spc].mn=tr[rrr].mn;
     59             tr[spc].mnp=tr[rrr].mnp;
     60         }
     61     }
     62     return ;
     63 }
     64 void trr(int spc)
     65 {
     66     if(!spc)
     67         return ;
     68     tr[spc].lzt^=1;
     69     swap(lll,rrr);
     70     return ;
     71 }
     72 void pushdown(int spc)
     73 {
     74     if(tr[spc].lzt)
     75     {
     76         tr[spc].lzt=0;
     77         trr(lll);
     78         trr(rrr);
     79     }
     80     return ;
     81 }
     82 void recal(int spc)
     83 {
     84     if(!tr[spc].anc)
     85         recal(tr[spc].fa);
     86     pushdown(spc);
     87     return ;
     88 }
     89 void rotate(int spc)
     90 {
     91     int f=tr[spc].fa;
     92     bool k=whc(spc);
     93     tr[f].ch[k]=tr[spc].ch[!k];
     94     tr[spc].ch[!k]=f;
     95     if(tr[f].anc)
     96     {
     97         tr[spc].anc=1;
     98         tr[f].anc=0;
     99     }else
    100         tr[tr[f].fa].ch[whc(f)]=spc;
    101     tr[spc].fa=tr[f].fa;
    102     tr[f].fa=spc;
    103     tr[tr[f].ch[k]].fa=f;
    104     pushup(f);
    105     pushup(spc);
    106     return ;
    107 }
    108 void splay(int spc)
    109 {
    110     recal(spc);
    111     while(!tr[spc].anc)
    112     {
    113         int f=tr[spc].fa;
    114         if(tr[f].anc)
    115         {
    116             rotate(spc);
    117             return ;
    118         }
    119         if(whc(spc)^whc(f))
    120             rotate(spc);
    121         else
    122             rotate(f);
    123         rotate(spc);
    124     }
    125     return ;
    126 }
    127 void access(int spc)
    128 {
    129     int lst=0;
    130     while(spc)
    131     {
    132         splay(spc);
    133         tr[rrr].anc=1;
    134         tr[lst].anc=0;
    135         rrr=lst;
    136         pushup(spc);
    137         lst=spc;
    138         spc=tr[spc].fa;
    139     }
    140     return ;
    141 }
    142 void Mtr(int spc)
    143 {
    144     access(spc);
    145     splay(spc);
    146     trr(spc);
    147     return ;
    148 }
    149 void split(int x,int y)
    150 {
    151     Mtr(x);
    152     access(y);
    153     splay(y);
    154     return ;
    155 }
    156 int finf(int spc)
    157 {
    158     access(spc);
    159     splay(spc);
    160     while(lll)
    161         spc=lll;
    162     return spc;
    163 }
    164 void link(int x,int y)
    165 {
    166     Mtr(x);
    167     tr[x].fa=y;
    168     return ;
    169 }
    170 void cut(int x,int y)
    171 {
    172     split(x,y);
    173     tr[x].fa=tr[y].ls=0;
    174     tr[x].anc=1;
    175     pushup(y);
    176     return ;
    177 }
    178 void Insert(int frm,int twd,int spc,int Time)
    179 {
    180     if(frm==twd)
    181     {
    182         num++;
    183         odd[spc]=true;
    184         return ;
    185     }
    186     Mtr(frm);
    187     if(finf(twd)==frm)
    188     {
    189         int x=tr[twd].mnp-E;
    190         if(e[x].dl<Time)
    191         {
    192             onr[x]=false;
    193             onr[spc]=true;
    194             if(tr[twd].sum%2==0)
    195             {
    196                 odd[x]=true;
    197                 num++;
    198             }
    199             cut(e[x].f,x+E);
    200             cut(e[x].t,x+E);
    201             link(frm,spc+E);
    202             link(twd,spc+E);
    203         }else{
    204             if(tr[twd].sum%2==0)
    205             {
    206                 odd[spc]=true;
    207                 num++;
    208             }
    209         }
    210     }else{
    211         link(frm,spc+E);
    212         link(twd,spc+E);
    213         onr[spc]=true;
    214     }
    215     return ;
    216 }
    217 void Delete(int frm,int twd,int spc)
    218 {
    219     if(onr[spc])
    220     {
    221         cut(frm,spc+E);
    222         cut(twd,spc+E);
    223         onr[spc]=false;
    224         return ;
    225     }
    226     if(odd[spc])
    227     {
    228         odd[spc]=false;
    229         num--;
    230     }
    231     return ;
    232 }
    233 bool cmp(Event x,Event y)
    234 {
    235     return x.tpc<y.tpc;
    236 }
    237 int main()
    238 {
    239     scanf("%d%d%d",&n,&m,&T);
    240     for(int i=1;i<=n;i++)
    241     {
    242         tr[i].anc=1;
    243         tr[i].tip=0x3f3f3f3f;
    244     }
    245     for(int i=1;i<=m;i++)
    246     {
    247         int a,b,c,d;
    248         scanf("%d%d%d%d",&a,&b,&c,&d);
    249         ev[++cnt]=(Event){0,a,b,c,i};
    250         ev[++cnt]=(Event){1,a,b,d,i};
    251         e[i]=(ent){a,b,d};
    252         int spc=i+E;
    253         tr[spc].anc=1;
    254         tr[spc].mn=d;
    255         tr[spc].tip=d;
    256         tr[spc].mnp=i;
    257         tr[spc].val=1;
    258     }
    259     sort(ev+1,ev+cnt+1,cmp);
    260     for(int i=1,hpn=1;i<=T;i++)
    261     {
    262         for(;(hpn<=cnt)&&(ev[hpn].tpc<i);hpn++)
    263         {
    264             Event x=ev[hpn];
    265             if(!x.cmd)
    266                 Insert(x.f,x.t,x.no,e[x.no].dl);
    267             else
    268                 Delete(x.f,x.t,x.no);
    269         }
    270         if(num)
    271             puts("No");
    272         else
    273             puts("Yes");
    274     }
    275     return 0;
    276 }
  • 相关阅读:
    Dropout:随机失活
    SGD的优化:SGD+Momentum、Nesterov Momentum、AdaGrad、 RMSProp、Adam
    Batch Normalization:批量归一化
    Zero-Centered:零均值化
    Activation Functions:激活函数
    Pooling Layer:池化层
    Convolution Layer:卷积层
    「狐狸」的模板库
    割点
    线段树基础知识详解
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116501.html
Copyright © 2011-2022 走看看