• [luogu7353]Tom & Jerry


    建立(广义)圆方树,具体如下——

    称原图中的点为圆点,对每一个点双建立方点,并向其包含的(圆)点连边

    记$V(a,b)$为(原图中)删除$a$后$b$所在连通块(的点集)

    称$u\rightarrow v$当且仅当圆方树上两点路径中相邻圆点在原图中有边相连

    结论:Tom能在有限次行动内获胜当且仅当满足以下条件之一

    • $\forall v\in V(a,b),a\rightarrow v$
    • $\exists u\in [1,n]$满足$\forall v\in [1,n],u\rightarrow v$

    引理:删除$a$后原图和圆方树(圆点)连通性相同

    根据引理,充分性显然(直接在圆方树上"逼"即可),下面考虑必要性:

    Jerry第一次移动到$a$子树内最深的不与祖父在原图中有边相连的圆点

    Tom要移动到$a$最后一步必然经过$a$的兄弟,且该兄弟能$\rightarrow $其子树内所有点(否则与$a$最深矛盾)

    根据第2个条件,其子树外存在其$\not\rightarrow $的点,进而重复此过程即可

     显然简单树形dp即可,时间复杂度为$o(n\log n)$,可以通过

    (带$\log$时因为dp时检验边是否存在&询问时找$y$所在子树)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 int n,m,q,V,x,y,st[N],dfn[N],low[N],sz[N],g[N],f[N];
     5 vector<int>e[N],E[N],son[N];vector<int>::iterator it;
     6 bool cmp(int x,int y){
     7     return dfn[x]<dfn[y];
     8 }
     9 bool find(int x,int y){
    10     it=lower_bound(e[x].begin(),e[x].end(),y);
    11     return (it!=e[x].end())&&((*it)==y);
    12 }
    13 void dfs1(int k,int fa){
    14     if (fa)st[++st[0]]=k;
    15     dfn[k]=low[k]=++dfn[0];
    16     for(int i:e[k])
    17         if (i!=fa){
    18             if (dfn[i])low[k]=min(low[k],dfn[i]);
    19             else{
    20                 dfs1(i,k),low[k]=min(low[k],low[i]);
    21                 if (low[i]>=dfn[k]){
    22                     E[++V].push_back(k),E[k].push_back(V);
    23                     while (E[V].back()!=i){
    24                         E[V].push_back(st[st[0]]);
    25                         E[st[st[0]--]].push_back(V);
    26                     }
    27                 }
    28             }
    29         }
    30 }
    31 void dfs2(int k,int fa){
    32     dfn[k]=++dfn[0],sz[k]=f[k]=1;
    33     if (k>n){
    34         for(int i:E[k])
    35             if ((i!=fa)&&(!find(fa,i))){f[k]=0;break;}
    36     }
    37     for(int i:E[k])
    38         if (i!=fa){
    39             dfs2(i,k),sz[k]+=sz[i],f[k]&=f[i];
    40             if (k<=n)son[k].push_back(i);
    41         }
    42 }
    43 void dfs3(int k,int fa){
    44     int cnt=0,pos=0;
    45     for(int i:E[k])
    46         if ((i!=fa)&&(!f[i]))cnt++,pos^=i;
    47     for(int i:E[k])
    48         if (i!=fa){
    49             g[i]=g[k];
    50             if ((cnt>1)||(cnt==1)&&(i!=pos))g[i]=0;
    51         } 
    52     if (k>n){
    53         for(int i:E[k])
    54             if (i!=fa){
    55                 if (!find(i,fa)){g[i]=0;continue;}
    56                 for(int j:E[k])
    57                     if ((j!=fa)&&(j!=i)&&(!find(i,j))){g[i]=0;break;}
    58             }
    59     }
    60     for(int i:E[k])
    61         if (i!=fa)dfs3(i,k);
    62 }
    63 int main(){
    64     scanf("%d%d%d",&n,&m,&q);
    65     for(int i=1;i<=m;i++){
    66         scanf("%d%d",&x,&y);
    67         e[x].push_back(y),e[y].push_back(x);
    68     }
    69     for(int i=1;i<=n;i++)sort(e[i].begin(),e[i].end());
    70     V=n,dfs1(1,0);
    71     dfn[0]=0,dfs2(1,0);
    72     g[1]=1,dfs3(1,0);
    73     for(int i=1;i<=n;i++)
    74         if (f[i]&g[i]){
    75             while (q--)printf("Yes\n");
    76             return 0;
    77         }
    78     while (q--){
    79         scanf("%d%d",&x,&y);
    80         if ((dfn[y]<dfn[x])||(dfn[x]+sz[x]<=dfn[y])){
    81             if (g[x])printf("Yes\n");
    82             else printf("No\n");
    83         }
    84         else{
    85             it=--upper_bound(son[x].begin(),son[x].end(),y,cmp);
    86             if (f[*it])printf("Yes\n");
    87             else printf("No\n");
    88         }
    89     }
    90     return 0;
    91 } 
    View Code
  • 相关阅读:
    删除重复行的DataFrame
    http各个版本(1/1.1/2)对比
    merge()、. join()和concat()合并Pandas中的数据
    openssl windows 平台编译x86 x64
    openssl windows 平台使用 VS2017 编译openssl源码
    openssl des CBC
    openssl des ECB
    ffmpeg des
    网狐棋牌游戏用户数据库 开发文档
    cmake 附加库目录 附加包含头文件目录 链接库 镜像不安全 宏定义 一个完整的cmake小项目
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/16298724.html
Copyright © 2020-2023  润新知