• cogs 2383. [Hnoi2014]世界树 WD


    2383. [Hnoi2014]世界树

    ★★★   输入文件:worldtree.in   输出文件:worldtree.out   简单对比
    时间限制:2 s   内存限制:512 MB

    【题目描述】

    世界树是一棵无比巨大的树,它伸出的枝干构成了整个世界。在这里,生存着各种各样的种族和生灵,他们共同信奉着绝对公正公平的女神艾莉森,在他们的信条里,公平是使世界树能够生生不息、持续运转的根本基石。
    世界树的形态可以用一个数学模型来描述:世界树中有n个种族,种族的编号分别从1到n,分别生活在编号为1到n的聚居地上,种族的编号与其聚居地的编号相同。有的聚居地之间有双向的道路相连,道路的长度为1。保证连接的方式会形成一棵树结构,即所有的聚居地之间可以互相到达,并且不会出现环。定义两个聚居地之间的距离为连接他们的道路的长度;例如,若聚居地a和b之间有道路,b和c之间有道路,因为每条道路长度为1而且又不可能出现环,所卧a与c之间的距离为2。
    出于对公平的考虑,第i年,世界树的国王需要授权m[i]个种族的聚居地为临时议事处。对于某个种族x(x为种族的编号),如果距离该种族最近的临时议事处为y(y为议事处所在聚居地的编号),则种族x将接受y议事处的管辖(如果有多个临时议事处到该聚居地的距离一样,则y为其中编号最小的临时议事处)。
    现在国王想知道,在q年的时间里,每一年完成授权后,当年每个临时议事处将会管理多少个种族(议事处所在的聚居地也将接受该议事处管理)。 现在这个任务交给了以智慧著称的灵长类的你:程序猿。请帮国王完成这个任务吧。

    【输入格式】

    第一行为一个正整数n,表示世界树中种族的个数。
    接下来n-l行,每行两个正整数x,y,表示x聚居地与y聚居地之间有一条长度为1的双
    向道路。接下来一行为一个正整数q,表示国王询问的年数。
    接下来q块,每块两行:
    第i块的第一行为1个正整数m[i],表示第i年授权的临时议事处的个数。
    第i块的第二行为m[i]个正整数h[l]、h[2]、…、h[m[i]],表示被授权为临时议事处的聚居地编号(保证互不相同)。

    【输出格式】

    输出包含q行,第i行为m[i]个整数,该行的第j(j=1,2…,,m[i])个数表示第i年被授权的聚居地h[j]的临时议事处管理的种族个数。

    【样例输入】

    10 
      2 1 
      3 2 
      4 3 
      5 4 
      6 1 
      7 3 
      8 3 
      9 4 
      10 1 
      5 
      2 
      6 1   
      5 
      2 7 3 6 9   
      1 
      8  
      4 
      8 7 10 3   
      5 
      2 9 3 5 8 

    【样例输出】

    1 9   
      3 1 4 1 1   
      10  
      1 1 3 5   
      4 1 3 1 1 

    【提示】


    N<=300000, q<=300000,m[1]+m[2]+…+m[q]<=300000

    cogs:3点,luogu:AT

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<string>
      6 #include<queue>
      7 
      8 using namespace std;
      9 const int N=3000010;
     10 const int Maxn=9999999;
     11 
     12 int n;
     13 int Q;
     14 int now=1;
     15 int head[N];
     16 int m[N];
     17 int belong[N];
     18 int dis[N];
     19 bool vis[N];
     20 int Answer[N];
     21 int sp[N];
     22 queue<int>q;
     23 
     24 struct node{
     25     int u,v,w,nxt;
     26 }E[N];
     27 
     28 
     29 inline int read()
     30 {
     31     int x=0;
     32     char c=getchar();
     33     while(c<'0'||c>'9')c=getchar();
     34     while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();
     35     return x;
     36 }
     37 
     38 inline void Add(int u,int v)
     39 {
     40     E[now].u=u;
     41     E[now].v=v;
     42     E[now].w=1;
     43     E[now].nxt=head[u];
     44     head[u]=now++;
     45 }
     46 
     47 inline void spfa(int start)
     48 {
     49     while(!q.empty())q.pop();
     50     
     51     for(int i=1;i<=n;i++)
     52         sp[i]=Maxn,vis[i]=0;
     53         
     54     sp[start]=0;
     55     vis[start]=1;
     56     q.push(start);
     57     while(!q.empty())
     58     {
     59         int top=q.front();
     60         q.pop();
     61         vis[top]=0;
     62         for(int i=head[top];i!=-1;i=E[i].nxt)
     63         {
     64             if(sp[E[i].v]>sp[E[i].u]+E[i].w)
     65             {
     66                 sp[E[i].v]=sp[E[i].u]+E[i].w;
     67                 if(!vis[E[i].v])
     68                     q.push(E[i].v),vis[E[i].v]=1;
     69             }
     70         }
     71     }
     72     for(int i=1;i<=n;i++)
     73     {
     74         if(sp[i]<=dis[i])
     75         {
     76             if(sp[i]<dis[i])belong[i]=start;
     77             else belong[i]=min(belong[i],start);
     78             dis[i]=sp[i];
     79         } 
     80     }
     81 }
     82 
     83 int main()
     84 {
     85     freopen("worldtree.in","r",stdin);
     86     freopen("worldtree.out","w",stdout);
     87     
     88     n=read();
     89     for(int i=1;i<=n;i++)
     90         head[i]=-1;
     91     
     92     for(int i=1;i<n;i++)
     93     {
     94         int u=read(),v=read();
     95         Add(u,v);
     96         Add(v,u);
     97     }
     98     Q=read();
     99     while(Q--)
    100     {
    101         int z=read();
    102         
    103         memset(belong,Maxn,sizeof(belong));
    104         memset(Answer,0,sizeof(Answer));
    105         memset(dis,Maxn,sizeof(dis));
    106         
    107         for(int i=1;i<=z;i++)
    108             m[i]=read();
    109         for(int i=1;i<=z;i++)
    110             spfa(m[i]);
    111         for(int i=1;i<=n;i++)
    112             Answer[belong[i]]++;
    113         for(int i=1;i<=z;i++)
    114             printf("%d ",Answer[m[i]]);
    115             
    116         printf("
    ");
    117     }
    118     
    119     return 0;
    120 }

     WD代码:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #define N 300010
     4 #define inf 1000000000
     5 int n,x,y,Q,m;
     6 int shu,first[N];
     7 struct edge{int v,nx;}o[N<<1];
     8 inline void add(int u,int v){o[++shu].v=v,o[shu].nx=first[u],first[u]=shu;}
     9 int cnt,fa[N],size[N],dep[N],ord[N],son[N],top[N],seq[N];
    10 int a[N],b[N],Fa[N],X[N],Y[N],st[N],p[N],Ans[N],val[N];
    11 inline bool cmp(int x,int y){return ord[x]<ord[y];}
    12 inline void dfs(int x){
    13     dep[x]=dep[fa[x]]+1,size[x]=1;
    14     for(int i=first[x];i;i=o[i].nx){
    15         if(o[i].v==fa[x])continue;
    16         fa[o[i].v]=x,dfs(o[i].v),size[x]+=size[o[i].v];
    17         if(size[o[i].v]>size[son[x]])son[x]=o[i].v;
    18     }
    19 }
    20 inline void dfs(int x,int y){
    21     top[x]=y,ord[x]=++cnt,seq[cnt]=x;
    22     if(son[x])dfs(son[x],y);
    23     for(int i=first[x];i;i=o[i].nx){
    24         if(o[i].v==fa[x]||o[i].v==son[x])continue;
    25         dfs(o[i].v,o[i].v);
    26     }
    27 }
    28 inline int lca(int x,int y){
    29     for(;top[x]!=top[y];x=fa[top[x]])
    30         if(dep[top[x]]<dep[top[y]])std::swap(x,y);
    31     return dep[x]<dep[y]?x:y;
    32 }
    33 inline int get(int x,int d){
    34     for(;dep[top[x]]>d;x=fa[top[x]]);
    35     return seq[ord[x]-dep[x]+d];
    36 }
    37 inline void Min(int x,int y,int z){
    38     if(X[x]>X[y]+z||(X[x]==X[y]+z&&Y[x]>Y[y]))
    39         X[x]=X[y]+z,Y[x]=Y[y];
    40 }
    41 int main(){
    42     scanf("%d",&n);
    43     for(int i=1;i<n;++i)scanf("%d%d",&x,&y),add(x,y),add(y,x);
    44     dfs(1),dfs(1,1);
    45     for(scanf("%d",&Q);Q--;){
    46         int cnt=0;
    47         scanf("%d",&m);
    48         for(int i=1;i<=m;++i)scanf("%d",&a[i]),p[++cnt]=b[i]=a[i],X[a[i]]=0,Y[a[i]]=a[i];
    49         std::sort(a+1,a+m+1,cmp);
    50         for(int i=1,tail=0;i<=m;++i)if(tail){
    51             int t=lca(st[tail],a[i]);
    52             for(;dep[st[tail]]>dep[t];--tail)
    53                 if(dep[st[tail-1]]<=dep[t])Fa[st[tail]]=t;
    54             if(st[tail]!=t)Fa[t]=st[tail],st[++tail]=p[++cnt]=t,X[t]=inf,Y[t]=0;
    55             st[++tail]=a[i],Fa[a[i]]=t;
    56         }else st[++tail]=a[i],Fa[a[i]]=0;
    57         std::sort(p+1,p+cnt+1,cmp);
    58         for(int i=cnt;i>1;--i)Min(Fa[p[i]],p[i],dep[p[i]]-dep[Fa[p[i]]]);
    59         for(int i=2;i<=cnt;++i)Min(p[i],Fa[p[i]],dep[p[i]]-dep[Fa[p[i]]]);
    60         for(int i=1;i<=cnt;++i){
    61             x=p[i],y=Fa[x],val[x]=size[x];
    62             if(i==1){
    63                 Ans[Y[x]]+=n-size[x];
    64                 continue;
    65             }
    66             int t=get(x,dep[y]+1),sum=size[t]-size[x];
    67             val[y]-=size[t];
    68             if(Y[x]==Y[y]){
    69                 Ans[Y[x]]+=sum;
    70                 continue;
    71             }
    72             t=X[x]-X[y]+dep[x]+dep[y]+2;
    73             if(t&1^1&&Y[y]>Y[x])t-=2;
    74             t>>=1;
    75             t=size[get(x,t)]-size[x];
    76             Ans[Y[x]]+=t,Ans[Y[y]]+=sum-t;
    77         }
    78         for(int i=1;i<=cnt;++i)
    79             Ans[Y[p[i]]]+=val[p[i]];
    80         for(int i=1;i<=m;++i)printf("%d ",Ans[b[i]]),Ans[b[i]]=0;
    81         puts("");
    82     }
    83 }
  • 相关阅读:
    Libevent库学习笔记
    最大的k个数问题
    MongoDB之整库备份还原单表collection备份还原
    精通MATLAB混合编程
    AutoCAD 2016中文版从入门到精通(第2版)
    MATLAB科学计算范例实战速查宝典
    Android系统应用开发实战详解
    AutoCAD快捷命令速查大全
    TCP IP入门经典(第5版)
    STC8系列单片机开发指南:面向处理器、程序设计和操作系统的分析与应用
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7017791.html
Copyright © 2020-2023  润新知