zoukankan      html  css  js  c++  java
  • hdu 5967 小R与手机(LCT裸题)

    题目链接:hdu 5967 小R与手机

    题意:

    有n个手机,每个手机有一个呼叫转移。如果形成了环就不能接通。

    现在有两个操作:

    1 询问打电话x,最终接到的是那个电话,如果有环,输出-1

    2 将x的呼叫转移改为y

    题解:

    用LCT来维护这个森林的关系。

    显然要形成环的话,肯定是树跟连向了该树内的点。

    所以特别维护一下树根的连向就行了。

     1 #include<bits/stdc++.h>
     2 #define F(i,a,b) for(int i=a;i<=b;i++)
     3 #define mst(a,b) memset(a,b,sizeof(a))
     4 using namespace std;
     5 
     6 namespace LCT
     7 {
     8     const int N=2e5+7;
     9     int f[N],son[N][2],tmp[N];bool rev[N];
    10     bool isroot(int x){return !f[x]||son[f[x]][0]!=x&&son[f[x]][1]!=x;}
    11     void rotate(int x){
    12         int y=f[x],w=son[y][1]==x;
    13         son[y][w]=son[x][w^1];
    14         if(son[x][w^1])f[son[x][w^1]]=y;
    15         if(f[y]){
    16             int z=f[y];
    17             if(son[z][0]==y)son[z][0]=x;else if(son[z][1]==y)son[z][1]=x;
    18         }
    19         f[x]=f[y];f[y]=x;son[x][w^1]=y;
    20     }
    21     void splay(int x){
    22         int s=1,i=x,y;tmp[1]=i;
    23         while(!isroot(x)){
    24             y=f[x];
    25             if(!isroot(y)){if((son[f[y]][0]==y)^(son[y][0]==x))rotate(x);else rotate(y);}
    26             rotate(x);
    27         }
    28     }
    29     void access(int x){for(int y=0;x;y=x,x=f[x])splay(x),son[x][1]=y;}
    30     int root(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}
    31     void makeroot(int x){access(x);splay(x);}
    32     void link(int x,int y){makeroot(x);f[x]=y;access(x);}
    33     void cutf(int x){access(x);splay(x);f[son[x][0]]=0;son[x][0]=0;}
    34     void cut(int x,int y){makeroot(x);cutf(y);}
    35 }
    36 
    37 using namespace LCT;
    38 int n,m,x,y,op,fa[N],a[N];
    39 
    40 void Link(int x,int y)
    41 {
    42     int rt=root(x);
    43     if(rt==x)fa[x]=0;else cutf(x);
    44     if(fa[rt]&&root(fa[rt])!=rt)
    45         link(rt,fa[rt]),fa[rt]=0;
    46     if(!y)return;
    47     if(root(y)==x)fa[x]=y;else link(x,y);
    48 }
    49 
    50 int main()
    51 {
    52     scanf("%d%d",&n,&m);
    53     F(i,1,n)
    54     {
    55         scanf("%d",a+i);
    56         if(a[i])Link(i,a[i]);
    57     }
    58     F(i,1,m)
    59     {
    60         scanf("%d",&op);
    61         if(op==1)scanf("%d%d",&x,&y),Link(x,y);
    62         else
    63         {
    64             scanf("%d",&x);
    65             int rt=root(x);
    66             if(fa[rt])puts("-1");
    67             else printf("%d
    ",rt);
    68         }
    69     }
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    oracle,sql server count函数 存储过程 判断 行数 注意事项
    js 跨域访问 获取验证码图片 获取header 自定义属性
    开发作中常用,实用工具推荐!
    phpcms
    php基础
    jQuery , js 写选项卡
    js, jquery实现全选,反选
    jQuery选择器
    学习jQuery
    javascript 与 java继承问题
  • 原文地址:https://www.cnblogs.com/bin-gege/p/7696033.html
Copyright © 2011-2022 走看看