zoukankan      html  css  js  c++  java
  • 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】统一天下
  • 相关阅读:
    软件的安全性应从哪几个方面去测试?
    目前主要的测试用例设计方法是什么?
    什么是软件质量?
    软件配置管理的作用?软件配置包括什么?
    什么是软件测试?软件测试的目的与原则
    软件生存周期及其模型是什么?
    软件的概念和特点?软件复用的含义?构件包括哪些?
    一台客户端有三百个客户与三百个客户端有三百个客户对服务器施压,有什么区别?
    在搜索引擎中输入汉字就可以解析到对应的域名,请问如何用LoadRunner进行测试。
    测试08
  • 原文地址:https://www.cnblogs.com/HYDcn666/p/13446863.html
Copyright © 2011-2022 走看看