其他分享
首页 > 其他分享> > CF1336A

CF1336A

作者:互联网

题目简化和分析:

明确一点这是一棵树。
为了保证每个工业城市的设置效益最大,应该设在最深的节点。
从深到浅,可以使用优先队列去实现。

设置一个的价值为 \(dep_u-siz_u-1\)。

关于作者一开始想反了,设置旅游城市,虽然可以做,但非常麻烦,于是看了别人大佬思路才明白。
错误原因在于,有可能儿子先设置了,而他的祖先却没有,会导致重复计算。
大家引以为戒。

Solution:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef double db;

const int N=4e5+50;
const int M=1e5+50;
const int Mod=1e9+7;

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

int n,k;
struct edge{
	int to,next;
}e[N];
int head[N],cnt;
void add_edge(int u,int v){
	++cnt;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}
priority_queue<int>q;
int siz[N],dep[N];
void dfs(int u,int p){
	dep[u]=dep[p]+1;
	for(int i=head[u];i;i=e[i].next){
		int y=e[i].to;
		if(y==p) continue;
		dfs(y,u);
		siz[u]+=siz[y];
	}
	q.push(dep[u]-siz[u]-1);
	++siz[u];
}
int main()
{
	n=read(),k=read();
	for(int i=1;i<n;++i){
		int u,v;
		u=read(),v=read();
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs(1,0);
	ll ans=0;
	while(k){
		--k;
		ans+=q.top();
		q.pop();
	}
	printf("%lld\n",ans);
	return 0;
}

标签:ch,const,int,siz,CF1336A,dep,read
来源: https://www.cnblogs.com/R-V-G/p/16531527.html