• [bzoj4025]二分图


      LCT一和别的东西扯上关系怎么就这么sxbk。。

      如果是问这个图是否是树的话就是常见姿势了:把边也当成点,然后用lct维护 以边的删除时间为权值 的最大生成树。

      但现在要求问是否是二分图。。。二分图就是说图中没有节点数为奇数的环。

      还是维护最大生成树,但是加边、形成环的时候的判断不一样了:

        会形成偶环的话就不连;(一条边如果可以和已有链形成偶环,并且这条边在之后和某些边构成一个奇环,那么已有链也可以和那些边构成奇环)

        会形成奇环的话就维护最大生成树,记录并在树中删除环上权值最小的边。

      记录一条边就是说,有这条边在的时候这个图里有奇环。所以如果图中被记录的边都过了删除时间的话,这个图就是二分图。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstring>
      4 using namespace std;
      5 const int maxn=300023;
      6 const int inf=1000233333;
      7 struct zs{
      8     int u,v,del,pre;
      9 }e[maxn];int tot,last[maxn];
     10 struct zs1{int pre;}e1[maxn];int last1[maxn];
     11 bool intree[maxn],sur[maxn];
     12 int sum[maxn],cnt;
     13  
     14 int fa[maxn],ch[maxn][2],mnpos[maxn],sz[maxn],st[maxn],top;
     15 bool rev[maxn];
     16  
     17 int i,j,k,n,m,T,x,y,l,r;
     18  
     19 int ra;char rx;
     20 inline int read(){
     21     rx=getchar(),ra=0;
     22     while(rx<'0'||rx>'9')rx=getchar();
     23     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
     24 }
     25  
     26 inline bool isrt(int x){
     27     return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
     28 }
     29 inline void pushdown(int x){
     30     if(!rev[x])return;
     31     swap(ch[x][0],ch[x][1]),rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,
     32     rev[x]=0;
     33 }
     34 inline void upd(int x){
     35     mnpos[x]= mnpos[ ch[x][ e[mnpos[ch[x][0]]].del>e[mnpos[ch[x][1]]].del ] ];
     36     if(x<=tot&&e[x].del<e[mnpos[x]].del)mnpos[x]=x;
     37     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+(x>tot);
     38 }
     39 inline void rotate(int x){
     40     int f=fa[x],gfa=fa[f],l=ch[f][1]==x,r=l^1;
     41     if(!isrt(f))ch[gfa][ ch[gfa][1]==f ]=x;
     42     fa[ ch[f][l]=ch[x][r] ]=f,fa[ fa[ ch[x][r]=f ]=x ]=gfa,
     43     upd(f);
     44 }
     45 inline void splay(int x){
     46     int f=x,gfa;
     47     for(st[top=1]=f;!isrt(f);st[++top]=(f=fa[f]));
     48     while(top)pushdown(st[top--]);
     49     while(!isrt(x)){
     50         f=fa[x],gfa=fa[f];
     51         if(!isrt(f))
     52             rotate(((ch[f][1]==x)^(ch[gfa][1]==f))?x:f);
     53         rotate(x);
     54     }
     55     upd(x);
     56 }
     57 inline void access(int x){
     58     for(int rc=0;x;rc=x,x=fa[x])
     59         splay(x),ch[x][1]=rc,upd(x);
     60 }
     61 inline void makert(int x){
     62     access(x),splay(x),rev[x]^=1;
     63 }
     64 inline void link(int x,int y){
     65     makert(x),fa[x]=y;
     66 }
     67 inline void cut(int x,int y){
     68     makert(x),access(y),splay(y),fa[x]=ch[y][0]=0,upd(y);
     69 }
     70 inline int getfa(int x){
     71     for(access(x),splay(x);ch[x][0];x=ch[x][0]);
     72     return x;
     73 }
     74  
     75  
     76 int main(){
     77     n=read(),m=read(),T=read();
     78     for(i=1;i<=m;i++){
     79         x=read()+m,y=read()+m,l=read()+1,r=read();
     80         if(l>r)continue;
     81         e[++tot]=(zs){x,y,r,last[l]};last[l]=tot;
     82         e1[tot].pre=last1[r],last1[r]=tot;
     83     }
     84     e[0].del=inf;
     85     for(i=1;i<=tot;i++)mnpos[i]=i;
     86     for(i=1;i<=T;i++){
     87         for(j=last[i];j;j=e[j].pre){
     88             x=e[j].u,y=e[j].v;//printf("x,y:  %d %d
    ",x,y);
     89             if(getfa(x)==getfa(y)){
     90                 makert(x),access(y),splay(y);int pos=mnpos[y];
     91                 if(sz[y]&1){
     92                     if(e[j].del>e[pos].del)
     93                         cut(e[pos].u,pos),cut(pos,e[pos].v),
     94                         sum[e[pos].del]++,cnt++,intree[pos]=0,sur[pos]=1,
     95                         link(x,j),link(j,y),intree[j]=1
     96                             ;//,printf("cut:(%d) %d %d
    link: %d %d
    ",pos,e[pos].u-m,e[pos].v-m,x,y);
     97                     else sum[e[j].del]++,cnt++,sur[j]=1;//,printf("!! %d
    ",e[pos].del);
     98                 }
     99             }else link(x,j),link(j,y),intree[j]=1;//,printf("link: %d %d
    ",x-m,y-m);
    100         }
    101         puts(cnt?"No":"Yes");
    102         for(j=last1[i];j;j=e1[j].pre)
    103             if(intree[j])/*printf("cut:(%d) ",j),*/cut(e[j].u,j),cut(j,e[j].v);//,printf("%d %d
    ",e[j].u-m,e[j].v-m);
    104             else if(sur[j])cnt--,sum[e[j].del]--;
    105         cnt-=sum[i];
    106     //  printf("  %d
    ",cnt);
    107     }
    108      
    109     return 0;
    110 }
    View Code

     因为update写炸调了半天。。。

  • 相关阅读:
    [文字雲產生器] Tagxedo 把文字串成雲、變成畫,印在 T-Shirt、馬克杯、詩袋….
    python学习(六)
    根据URL地址获取域名
    python学习(五)
    Linux下查看Mysql数据库端口的方法
    python学习(四)
    python学习(三)
    python学习(二)
    Java String删除字符串中间的某部分
    Spring的一个入门例子
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5243106.html
Copyright © 2020-2023  润新知