• AW252 树(点分治)


    题目地址


    注意点:

    • 枚举阶段时需要用dfs预处理每个点的深度.

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN=2e4,MAXM=3e4;
    struct Edge{
    	int from,to,w,nxt;
    }e[MAXM];
    int head[MAXN],edgeCnt=1;
    void addEdge(int u,int v,int w){
    	e[++edgeCnt].from=u;
    	e[edgeCnt].to=v;
    	e[edgeCnt].w=w;
    	e[edgeCnt].nxt=head[u];
    	head[u]=edgeCnt;
    }
    bool vis[MAXN],w[MAXN];
    int siz[MAXN];
    int pos,ans;
    void dfs_find(int restSiz,int x){
    	vis[x]=1;
    	siz[x]=1;
    	int maxSiz=0;
    	for(int i=head[x];i;i=e[i].nxt){
    		int nowV=e[i].to;
    		if(vis[nowV]||w[nowV])continue;
    		dfs_find(restSiz,nowV);
    		siz[x]+=siz[nowV];
    		maxSiz=max(maxSiz,siz[nowV]);
    	}
    	maxSiz=max(maxSiz,restSiz-siz[x]);
    	if(maxSiz<ans)ans=maxSiz,pos=x;
    }
    int dep[MAXN],tot,cnt[MAXN];
    int a[MAXN],b[MAXN];
    void dfs(int x){
    	vis[x]=1;
    	for(int i=head[x];i;i=e[i].nxt){
    		int nowV=e[i].to,nowW=e[i].w;
    		if(vis[nowV]||w[nowV])continue;
    		a[++tot]=nowV,b[nowV]=b[x];
    		cnt[b[x]]++;
    		dep[nowV]=dep[x]+nowW;//
    		dfs(nowV);
    	}
    }
    bool cmp(int x,int y){
    	return dep[x]<dep[y];
    }
    int Ans;
    void reset(){
    	memset(dep,0,sizeof(dep));
    	memset(cnt,0,sizeof(cnt));
    	memset(vis,0,sizeof(vis));
    	tot=1;
    }
    int k;
    void work(int restSiz,int x){
    	memset(vis,0,sizeof(vis));
    	ans=restSiz;
    	dfs_find(restSiz,x);
    	reset();
    	a[tot]=b[pos]=pos;
    	w[pos]=1,cnt[pos]++;
    	for(int i=head[pos];i;i=e[i].nxt){
    		int nowV=e[i].to,nowW=e[i].w;
    		if(vis[nowV]||w[nowV])continue;
    		a[++tot]=b[nowV]=nowV;
    		cnt[nowV]++,dep[nowV]=nowW;
    		dfs(nowV);
    	}
    	sort(a+1,a+1+tot,cmp);
    	int l=1,r=tot;
    	cnt[b[a[1]]]--;
    	while(l<r){
    		while(dep[a[l]]+dep[a[r]]>k)cnt[b[a[r--]]]--;
    		Ans+=r-l-cnt[b[a[l]]];
    		cnt[b[a[++l]]]--;
    	}
    	int nowU=pos;
    	for(int i=head[nowU];i;i=e[i].nxt){
    		int nowV=e[i].to;
    		if(w[nowV])continue;
    		work(siz[nowV],nowV);
    	}
    }
    void init(){
    	memset(head,0,sizeof(head));
    	edgeCnt=1;
    }
    int main(){
    	int n;
    	while(1){
    		scanf("%d%d",&n,&k);
    		if(!n)break;
    		init();
    		for(int i=1;i<=n-1;i++){
    			int u,v,cost;
    			scanf("%d%d%d",&u,&v,&cost);
    			addEdge(u,v,cost);
    			addEdge(v,u,cost);
    		}
    		memset(w,0,sizeof(w));
    		Ans=0;
    		work(n,1);
    		printf("%d
    ",Ans);
    	}
    	return 0;
    }
  • 相关阅读:
    demo2.css
    less的嵌套
    ddd.css
    LESS自学
    vue.js过滤器 “|”
    v-if,v-else数据绑定
    v-for基本用法
    在spring中使用JdbcTemplate进行数据库管理操作
    2013第四届蓝桥杯JavaB组省赛 第一题:世纪末的星期
    PTA L1-049 天梯赛座位分配 (20分)
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680540.html
Copyright © 2020-2023  润新知