zoukankan      html  css  js  c++  java
  • Acyclic Organic Compounds

    题意:

    给一以1为根的字符树,给出每个节点的字符与权值,记 $diff_{x}$ 为从 $x$ 出发向下走,能走到多少不同的字符串,求问最大的
    $diff_{x} + c_{x}$,并求有多少个 $diff_{x} + c_{x}$。

    解法:

    考虑$dfs$,从下到上启发式合并 $Trie$ 树,效率 $O(nlogn)$。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 #define N 300010
     6 
     7 using namespace std;
     8 
     9 struct edge
    10 {
    11     int x,to;
    12 }E[N<<1];
    13 
    14 struct node
    15 {
    16     node *ch[26];
    17     int siz;
    18     
    19     node* init()
    20     {
    21         siz=1;
    22         memset(ch,0,sizeof(ch));
    23         return this;
    24     };
    25 }spT[N<<1],*root[N];
    26 
    27 int n,m,totn,totE,ans,ansv;
    28 int fa[N],g[N],c[N];
    29 char S[N];
    30 
    31 void addedge(int x,int y)
    32 {
    33     E[++totE] = (edge){y,g[x]}; g[x]=totE;
    34     E[++totE] = (edge){x,g[y]}; g[y]=totE;
    35 }
    36 
    37 #define p E[i].x
    38 
    39 node* merge(node *p1,node *p2)
    40 {
    41     if(p1->siz < p2->siz) swap(p1,p2);
    42     for(int t=0;t<26;t++)
    43         if(p2->ch[t])
    44         {
    45             if(!p1->ch[t]) p1->ch[t]=p2->ch[t];
    46             else p1->ch[t] = merge(p1->ch[t], p2->ch[t]);
    47         }
    48     p1->siz=1;
    49     for(int t=0;t<26;t++)
    50         if(p1->ch[t]) p1->siz+=p1->ch[t]->siz;
    51     return p1;
    52 }
    53 
    54 void dfs(int x)
    55 {
    56     int tmp=S[x]-'a';
    57     root[x]=spT[++totn].init();
    58     root[x]->ch[tmp]=spT[++totn].init();
    59     for(int i=g[x];i;i=E[i].to)
    60         if(p!=fa[x])
    61         {
    62             fa[p]=x;
    63             dfs(p);
    64         }
    65     for(int i=g[x];i;i=E[i].to)
    66         if(p!=fa[x])
    67             root[x]->ch[tmp] = merge(root[x]->ch[tmp],root[p]);
    68     root[x]->siz = root[x]->ch[tmp]->siz;
    69     if(root[x]->siz+c[x] > ansv)
    70     {
    71         ansv = root[x]->siz+c[x];
    72         ans=1;
    73     }
    74     else if(root[x]->siz+c[x] == ansv) ans++;
    75 }
    76 
    77 int main()
    78 {
    79     while(~scanf("%d",&n))
    80     {
    81         for(int i=1;i<=n;i++) g[i]=0;
    82         totE=0;
    83         for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    84         S[0]='*';
    85         scanf("%s",S+1);
    86         ans=0;
    87         totn=ansv=0;
    88         for(int i=1,x,y;i<n;i++)
    89         {
    90             scanf("%d%d",&x,&y);
    91             addedge(x,y);
    92         }
    93         fa[1]=0;
    94         dfs(1);
    95         cout << ansv << endl << ans << endl;
    96     }
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    ActiveMQ的学习(四)(消息投递方式+死信队列+重发策略)
    ActiveMQ的学习(三)(ActiveMQ的消息事务和消息的确认机制)
    ActiveMQ的学习(二)(ActiveMQ的持久化)
    ActiveMQ的学习(一)(ActiveMQ和JMS的介绍)
    redis总结(持续更新)
    easyUI--搜索条件控件的处理
    bootstrap的下载和引用
    springMVC总结
    easyUi--datagrid的一些处理
    测试工作一
  • 原文地址:https://www.cnblogs.com/lawyer/p/6595721.html
Copyright © 2011-2022 走看看