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 }