zoukankan      html  css  js  c++  java
  • CF1452G

    CF1452G - Game On Tree

    题目大意

    A和B在树上Van游戏,每个人操作一些点

    A操作一个点(i),B操作一个点集(a_j)

    每轮A,B分别进行操作,可以对于自己的所有点任意移动1步或0步

    在某一轮,当A的点碰到B的点时游戏结束

    A希望尽量迟结束,B希望尽量早结束

    给定B的初始点集(a_j),对于A的每个初始点(i)判断多少轮结束


    分析

    由于B的操作显然是不停向A收缩直到碰到

    那么可以广搜求出每个点原地不动时被B干掉的时间(F_i)

    那么考虑A的移动过程,每一步可以到达一个点(u)

    必须满足在第(i)步所在的点(u)(F_u>i),否则结束游戏

    对于初始节点(u),不妨设最终结束的节点为(t),我们希望一路跑到(t)然后站住不动,此时答案就是(F_t)

    而实际上,任何一个点(u)能够跑到(t),等价于(dis(u,t)<F_t)

    Proof:

    由最短路三角不等式可知

    (forall (u,v)in Tree, dis_{v}-1leq dis_uleq dis_{v}+1)

    (dis_e)在树的路径上连续变化,不妨设移动路径为(p_i,iin[1,k],p_k=t,kleq F_t)

    若能在(F_t-1)的时间内到达(p_k),那么必然能在(F_t-2)的时间内到达(p_{k-1})

    进而归纳得到


    那么问题变成了,对于每个点(u),向周围(F_u-1)范围内的点对于(F_u)(max)

    容易点分治处理,复杂度为(O(nlog n))

    const int N=2e5+10,INF=1e9+10;
    
    int n,F[N],A[N];
    vector <int> G[N];
    queue <int> que;
    
    int mi,rt,sz[N],vis[N];
    void FindRt(int n,int u,int f){
    	int ma=0; sz[u]=1;
    	for(int v:G[u]) if(!vis[v] && v!=f) {
    		FindRt(n,v,u),sz[u]+=sz[v];
    		cmax(ma,sz[v]);
    	}
    	cmax(ma,n-sz[u]);
    	if(mi>ma) mi=ma,rt=u;
    }
    
    int dep[N],id[N],c,s[N];
    void dfs(int u,int f){
    	id[++c]=u;
    	for(int v:G[u]) if(v!=f && !vis[v]) {
    		dep[v]=dep[u]+1;
    		dfs(v,u);
    	}
    }
    void Div(int n,int u){
    	mi=1e9,FindRt(n,u,0),u=rt,vis[u]=1;
    	c=0,dep[u]=0,dfs(u,0);
    	rep(i,0,c) s[i]=0;
    	rep(i,1,c) {
    		int u=id[i];
    		if(F[u]>dep[u]) cmax(s[min(c,F[u]-1-dep[u])],F[u]);
    	}
    	drep(i,c-1,0) cmax(s[i],s[i+1]);
    	rep(i,1,c) cmax(A[id[i]],s[dep[id[i]]]);
    	for(int v:G[u]) if(!vis[v]) {
    		if(sz[v]>sz[u]) sz[v]=n-sz[u];
    		Div(sz[v],v);
    	}
    }
    
    int main(){
    	rep(i,2,n=rd()){
    		int u=rd(),v=rd();
    		G[u].pb(v),G[v].pb(u);
    	}
    	rep(i,1,n) F[i]=-1;
    	rep(i,1,rd()) {
    		int x=rd();
    		F[x]=0,que.push(x);
    	}
    	while(!que.empty()) {
    		int u=que.front(); que.pop();
    		for(int v:G[u]) if(F[v]==-1) 
    			F[v]=F[u]+1,que.push(v);
    	}
    	Div(n,1);
    	rep(i,1,n) printf("%d ",A[i]);
    }
    
  • 相关阅读:
    html5 canvas 渐变
    html5 canvas 画直线
    html5在canvas中插入图片
    Window文件夹右击菜单定制
    HTML中解决双击会选中文本的问题
    Linux 下修改mysql 字符集编码
    mysqlimport导入命令使用
    PAM 2500 荧光数据导出数据整合脚本
    Resources for Ecology and Evolution
    Plant Ecology Journal Club, 分享主题和文献列表 825, 2019年春
  • 原文地址:https://www.cnblogs.com/chasedeath/p/14782860.html
Copyright © 2011-2022 走看看