• JZOJ【NOIP2015模拟11.4】统一天下


     【思路】

    将两棵树重心相连,做树形DP

    易得

    Down[now]=∑Down[son]+Size[son]

    Up[son]=Up[now]+Size[1]-Size[son]*2+Down[now]-Down[son]

    初始化:Up[1]=0

    【注意事项】

    1.部分数据在JZ的辣鸡电脑上跑会爆栈,交到OJ就可以了

    2.什么?你不会求重心?

    https://oi-wiki.org/graph/tree-centroid/

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<string>
      5 #include<cstring>
      6 using namespace std;
      7 int n1,n2,m,h[300005],g[300005],wd[600005],c[6000005],dis[600005];
      8 int wnt,cnt,tot,rt1,rt2,wt[300005],size[600005],fa[600005];
      9 int x1[600005],x2[600005],y1[600005],y2[600005];
     10 long long up[6000005],down[6000005];
     11 long long ans;
     12 struct node
     13 {
     14     int next,to;
     15 }e[6000005],f[6000005],w[2000005];
     16 void add(int x,int y)
     17 {
     18     e[++cnt].to=y;
     19     e[cnt].next=h[x];
     20     h[x]=cnt;
     21 }
     22 void odd(int x,int y)
     23 {
     24     f[++tot].to=y;
     25     f[tot].next=g[x];
     26     g[x]=tot;
     27 }
     28 void add_edge(int x,int y)
     29 {
     30     w[++wnt].to=y;
     31     w[wnt].next=wd[x];
     32     wd[x]=wnt;
     33 }
     34 void get1(int x,int fa)
     35 {
     36     size[x]=1;
     37     wt[x]=0;
     38     for(int i=h[x];i;i=e[i].next)
     39     {
     40         int y=e[i].to;
     41         if(y!=fa)
     42         {
     43             get1(y,x);
     44             size[x]+=size[y];
     45             wt[x]=max(wt[x],size[y]);
     46         }
     47     }
     48     wt[x]=max(wt[x],n1-size[x]);
     49     if(rt1==0||wt[x]<wt[rt1])rt1=x;
     50 }
     51 void get2(int x,int fa)
     52 {
     53     size[x]=1;
     54     wt[x]=0;
     55     for(int i=g[x];i;i=f[i].next)
     56     {
     57         int y=f[i].to;
     58         if(y!=fa)
     59         {
     60             get2(y,x);
     61             size[x]+=size[y];
     62             wt[x]=max(wt[x],size[y]);
     63         }
     64     }
     65     wt[x]=max(wt[x],n2-size[x]);
     66     if(rt2==0||wt[x]<wt[rt2])rt2=x;
     67 }
     68 void dfs(int x)
     69 {
     70     size[x]=1;
     71     for(int i=wd[x];i;i=w[i].next)
     72     {
     73         int y=w[i].to;
     74         if(fa[x]!=y)
     75         {
     76             fa[y]=x;
     77             dfs(y);
     78             size[x]+=size[y];
     79             down[x]+=down[y]+size[y];
     80         }
     81     }
     82 }
     83 void bfs(int x)
     84 {
     85     int head=0,tail=1;c[1]=1;
     86     while(head<tail)
     87     {
     88         int x=c[++head];
     89         if(x==1)up[x]=0;
     90         else up[x]=up[fa[x]]+size[1]-size[x]+down[fa[x]]-down[x]-size[x];
     91         for(int i=wd[x];i;i=w[i].next)
     92         {
     93             int y=w[i].to;
     94             if(fa[x]!=y)
     95             {
     96                 c[++tail]=y;
     97             }
     98         }
     99     }
    100 }
    101 int main()
    102 {
    103     freopen("unite.in","r",stdin);
    104     freopen("unite.out","w",stdout);
    105     scanf("%d%d",&n1,&n2);
    106     for(int i=1,x,y;i<n1;i++)
    107     {
    108         scanf("%d%d",&x1[i],&y1[i]);
    109         add(x1[i],y1[i]);
    110         add(y1[i],x1[i]);
    111     }
    112     for(int i=1,x,y;i<n2;i++)
    113     {
    114         scanf("%d%d",&x2[i],&y2[i]);
    115         odd(x2[i],y2[i]);
    116         odd(y2[i],x2[i]);
    117     }
    118     get1(1,0);
    119     get2(1,0);
    120     for(int i=1,x,y;i<n1;i++)
    121     {
    122         add_edge(x1[i],y1[i]);
    123         add_edge(y1[i],x1[i]);
    124     }
    125     for(int i=1,x,y;i<n2;i++)
    126     {
    127         add_edge(x2[i]+n1,y2[i]+n1);
    128         add_edge(y2[i]+n1,x2[i]+n1);
    129     }
    130     add_edge(rt1,rt2+n1);
    131     m=n1+n2;
    132     dfs(1);    
    133     bfs(1);
    134     for(int i=1;i<=m;i++)
    135     {
    136         ans+=up[i]+down[i];
    137     }
    138     printf("%lld
    ",ans/2);
    139     fclose(stdin);fclose(stdout);
    140 }
    【NOIP2015模拟11.4】统一天下
  • 相关阅读:
    PHP中new static()与new self()的比较
    【程序员感悟系列】 由一点业务说开去
    配置管理工具 Puppet的安装和使用
    【读书笔记】大话设计模式
    博客还是要写起来 2016.08.13 周六
    linux启动SSH及开机自动启动
    Monkey日志信息的11种Event percentages
    Monkey官方帮助翻译&介绍
    Github问题An error occurred trying to download
    怎样克服拖延症,马上采取行动?
  • 原文地址:https://www.cnblogs.com/HYDcn666/p/13446863.html
Copyright © 2020-2023  润新知