2020.02.05日常总结

C F 982 C     C u t   t h e m   a l l ! \color{green}{CF982C\ \ \ Cut\ them\ all!}

\color{blue}{【题意】:}

\color{orange}{【题目大意】:}

现在有一棵有 N N 个节点的树,你可以删去树中的一些边使其成为森林,你的任务是删去最多的边使得每一棵森林中的树的大小为偶数,并输出删去的边数。

\color{orange}{【输入格式】:}

第一行为一个整数,即节点数 N 1 n 1 × 1 0 5 N(1\leq n\leq 1\times 10^5)

接下来 N 1 N-1 行每行包括两个整数 u u v v ,表示树中连接 u u v v 的两条边。保证 u u v v 1 1 N N 的范围内,同时保证给出的图是一棵树。

\color{orange}{【输出格式】:}

一个整数,表示你可以删去的最多的边数。

\color{blue}{【思路】:}

首先,以 1 1 为根求出所有点的 s i z e size f a fa 。然后从叶子到根枚举,当一个点的 s i z e size 大小为偶数时,就把这个点的子树独自为一棵树。同时别忘了让它父亲的 s i z e size 减去它自己的 s i z e size

\color{blue}{【代码】:}
代码来源于洛谷用户HPXXZYY,请勿直接复制
codeforces账号也是HPXXZYY
const int N=1e5+100;
struct node{
	int next,to;
}e[N<<1];int h[N],tot;
inline void add(int a,int b){
	e[++tot]=(node){h[a],b};h[a]=tot;
	e[++tot]=(node){h[b],a};h[b]=tot;
}
int n,size[N],fa[N],ans;
void dfs_init(int u,int pa){
	size[u]=1;fa[u]=pa;int i;
	for(i=h[u];i;i=e[i].next){
		register int to=e[i].to;
		if (to==pa) continue;
		dfs_init(to,u);
		size[u]+=size[to];
	}
}
void calc_answer(int u){
	for(int i=h[u];i;i=e[i].next)
		if (e[i].to!=fa[u])
			calc_answer(e[i].to);
	if (size[u]%2==0){
		ans++;size[fa[u]]-=size[u];
	}
}
int main(){
	freopen("t1.in","r",stdin);
	n=read();ans=0;size[1]=0;
	for(int i=1;i<n;i++)
		add(read(),read());
	if (n%2){
		printf("-1");
		return 0;
	}
	dfs_init(1,-1);
	calc_answer(1);
	cout<<ans-1;
	return 0;
}

C F 1056 D     D e c o r a t e   A p p l e   T r e e \color{green}{CF1056D\ \ \ Decorate\ Apple\ Tree}

\color{blue}{【题意】:}

\color{orange}{【题目大意】:}
给你一个 n n 个结点以 1 1 为根的树,给这 n n 个结点任意染色,定义一个点为快乐结点当且仅当这个结点的子树上所有点颜色 \color{red}{均不相同} 。求出对于 1 n 1\sim n 中的每一个 k k ,求快乐结点数大于等于 k k 所需要的最少颜色数。

\color{orange}{【输入格式】:}
第一行一个数 n ( 1 n 1 0 5 ) n(1\le n\le 10^5) ,表示结点数量。

第二行 n 1 n-1 个数 p i p_i ,表示第 i i 个结点的父亲结点 ( 1 p i < i ) (1\le p_i<i)

\color{orange}{【输出格式】:}
一行, n n 个数,表示对于 1 n 1\sim n 中的每一个 k k 快乐节点数大于等于 k k 时所需的最少颜色数。

感谢洛谷的翻译,侵权必删!!!

\color{blue}{【思路】:}

考虑一棵子树,记其叶子节点为 f f ,那么我们需要 f f 种颜色让这棵子树的所有节点变成快乐节点。所有我们只需求出所有的 f f ,排序,输出即可。

\color{blue}{【代码】:}
代码来源于洛谷用户HPXXZYY,请勿直接复制
codeforces账号也是HPXXZYY
const int N=1e5+100;
vector<int> G[N];
int f[N],n,ans;
void dfs(int u){
	f[u]=0;register int i;
	for(i=0;i<G[u].size();i++){
		register int to=G[u][i];
		dfs(to);f[u]+=f[to];
	}
	if (f[u]==0) f[u]=1;
}
int main(){
	n=read();ans=-1;
	for(int i=2;i<=n;i++)
		G[read()].push_back(i);
	dfs(1);sort(f+1,f+n+1);
	for(int i=1;i<=n;i++)
		printf("%d ",f[i]);
	return 0;
}
发布了103 篇原创文章 · 获赞 4 · 访问量 6734

猜你喜欢

转载自blog.csdn.net/ZHUYINGYE_123456/article/details/104181774