• 【CF1252F】Regular Forestation(重心,树同构)


    题意:给定一棵n个点的树,问删去某个点之后所有的树同构,这样分割出来的树最多能有几棵

    n<=4000

    思路:分割成至少两个size相等的联通块之后size必定小于n/2,与树的重心的定义相同

    预处理出重心(0,1或2个)之后上无根树同构板子

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 typedef unsigned int uint;
      5 typedef unsigned long long ull;
      6 typedef long double ld;
      7 typedef pair<int,int> PII;
      8 typedef pair<ll,ll> Pll;
      9 typedef vector<int> VI;
     10 typedef vector<PII> VII;
     11 typedef pair<ll,ll>P;
     12 #define N  200010
     13 #define M  1000000
     14 #define INF 1e9
     15 #define fi first
     16 #define se second
     17 #define MP make_pair
     18 #define pb push_back
     19 #define pi acos(-1)
     20 #define mem(a,b) memset(a,b,sizeof(a))
     21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
     22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
     23 #define lowbit(x) x&(-x)
     24 #define Rand (rand()*(1<<16)+rand())
     25 #define id(x) ((x)<=B?(x):m-n/(x)+1)
     26 #define ls p<<1
     27 #define rs p<<1|1
     28 #define fors(i) for(auto i:e[x]) if(i!=p)
     29 
     30 const int MOD=1e9+7,inv2=(MOD+1)/2;
     31       double eps=1e-6;
     32       int dx[4]={-1,1,0,0};
     33       int dy[4]={0,0,-1,1};
     34 
     35 int head[N],vet[N],nxt[N],sz[N],mx[N],d[N],tot,Size,root;
     36 
     37 int read()
     38 {
     39    int v=0,f=1;
     40    char c=getchar();
     41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     43    return v*f;
     44 }
     45 
     46 ll readll()
     47 {
     48    ll v=0,f=1;
     49    char c=getchar();
     50    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     51    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     52    return v*f;
     53 }
     54 
     55 void add(int a,int b)
     56 {
     57     nxt[++tot]=head[a];
     58     vet[tot]=b;
     59     head[a]=tot;
     60 }
     61 
     62 void dfs1(int u,int fa)
     63 {
     64     int e=head[u];
     65     sz[u]=1,mx[u]=0;
     66     while(e)
     67     {
     68         int v=vet[e];
     69         if(v!=fa)
     70         {
     71             dfs1(v,u);
     72             sz[u]+=sz[v];
     73             mx[u]=max(mx[u],sz[v]);
     74         }
     75         e=nxt[e];
     76     }
     77 }
     78 
     79 int ra[N];
     80 
     81 int pw(int x,int y)
     82 {
     83     int res=1;
     84     while(y)
     85     {
     86         if(y&1) res=1ll*res*x%MOD;
     87         x=1ll*x*x%MOD;
     88         y>>=1;
     89     }
     90     return res;
     91 }
     92 
     93 int inv(int x)
     94 {
     95     return pw(x,MOD-2);
     96 }
     97 
     98 struct Sub
     99 {
    100     VI S;
    101     int d1,d2,H1,H2;
    102     Sub(){d1=d2=0; S.clear();}
    103 
    104     void add(int d,int v)
    105     {
    106         S.pb(v);
    107         if(d>d1) d2=d1,d1=d;
    108          else if(d>d2) d2=d;
    109     }
    110 
    111     int Hash()
    112     {
    113         H1=H2=1;
    114         for(int i:S)
    115         {
    116             H1=1ll*H1*(ra[d1]+i)%MOD;
    117             H2=1ll*H2*(ra[d2]+i)%MOD;
    118         }
    119         return H1;
    120     }
    121 
    122     PII del(int d,int v)
    123     {
    124         if(d==d1) return {d2+1,1ll*H2*inv(ra[d2]+v)%MOD};
    125         return {d1+1,1ll*H1*inv(ra[d1]+v)%MOD};
    126     }
    127 };
    128 
    129 PII U[N];
    130 int n,i,x,y,A[N];
    131 Sub T[N];
    132 
    133 void prepare(int n)
    134 {
    135     rep(i,0,n) ra[i]=rand()%MOD;
    136 }
    137 
    138 void dfsD(int u,int p)
    139 {
    140     Size++;
    141     T[u]=Sub();
    142     int e=head[u];
    143     while(e)
    144     {
    145         int v=vet[e];
    146         if(v!=p)
    147         {
    148             dfsD(v,u);
    149             T[u].add(T[v].d1+1,T[v].H1);
    150         }
    151         e=nxt[e];
    152     }
    153     T[u].Hash();
    154 }
    155 
    156 void dfsU(int u,int p)
    157 {
    158     if(p!=root) T[u].add(U[u].fi,U[u].se);
    159     A[u]=T[u].Hash();
    160     int e=head[u];
    161     while(e)
    162     {
    163         int v=vet[e];
    164         if(v!=p)
    165         {
    166             U[v]=T[u].del(T[v].d1+1,T[v].H1);
    167             dfsU(v,u);
    168         }
    169         e=nxt[e];
    170     }
    171 }
    172 
    173 int isok(int root,int block)
    174 {
    175     int t[5000],c[5000];
    176     int s=0;
    177     int e=head[root];
    178     while(e)
    179     {
    180         int v=vet[e];
    181         rep(i,1,n) A[i]=0;
    182         Size=0;
    183         dfsD(v,root);
    184         dfsU(v,root);
    185         if(Size!=block) return 0;
    186         s++;
    187         if(s==1)
    188         {
    189             sort(A+1,A+n+1);
    190             rep(i,1,n) c[i]=A[i];
    191         }
    192          else
    193          {
    194              sort(A+1,A+n+1);
    195              rep(i,1,n)
    196               if(A[i]!=c[i]) return 0;
    197          }
    198         e=nxt[e];
    199     }
    200     return 1;
    201 }
    202 
    203 int main()
    204 {
    205     VI r;
    206     srand(23333);
    207     prepare(5000);
    208     n=read();
    209     rep(i,1,n) head[i]=d[i]=0;
    210     tot=0;
    211     rep(i,1,n-1)
    212     {
    213         int x=read(),y=read();
    214         add(x,y);
    215         add(y,x);
    216         d[x]++; d[y]++;
    217     }
    218     dfs1(1,0);
    219 
    220     r.clear();
    221 
    222     rep(i,1,n)
    223      if(d[i]>=2&&max(mx[i],n-sz[i])<=n/2) r.pb(i);
    224 
    225 
    226     int ans=0;
    227     for(int i=0;i<r.size();i++)
    228     {
    229         root=r[i];
    230         if(isok(r[i],mx[r[i]])) ans=max(ans,d[r[i]]);
    231     }
    232     if(ans==0) printf("-1
    ");
    233      else printf("%d
    ",ans);
    234     return 0;
    235 }
  • 相关阅读:
    Oracle:PL/SQL--流程控制——作业练习:向表中循环插入ID编号
    Oracle:PL/SQL--流程控制(三)——循环结构:loop、while-loop、for-loop
    Oracle:PL/SQL--流程控制(三)——循环结构:loop、while-loop、for-loop
    Oracle:PL/SQL--打开控制台or关闭控制台
    Win10远程桌面及防火墙配置
    H3C-Telnet
    网络工程师(软考)心得
    《网络工程师 考前冲刺100题》思维导图
    《2019上半年网络工程师考试大纲》
    网络设计:搭建校园网(组网工程课设)【译】
  • 原文地址:https://www.cnblogs.com/myx12345/p/11801773.html
Copyright © 2020-2023  润新知