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("\n");
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 }

 

posted @ 2017-06-15 14:57  ioioioioioio  阅读(168)  评论(0编辑  收藏  举报