码迷,mamicode.com
首页 > 其他好文 > 详细

GDFZOJ 美丽树

时间:2016-10-22 11:46:59      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:namespace   ons   #include   main   cst   代码   algo   space   ++   

题意:

给出一棵有n个点的树,边是有向边,定义一棵美丽子树为:一个点及其子树所有点的编号恰好为一段连续的数字则称之为美丽,现在求有多少棵美丽子树?

 

题解:

一段连续的数字必定有一个最大的数字和最小的数字,如果现在知道最大和最小的数是什么了,判断是否连续就可以通过找出数的个数了。。

所以需要找出:一棵子树的最大值,最小值,节点个数

 

代码:

#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1e5 + 7;
int n, c[N], r[N], root, ans, siz[N], mini[N], maxi[N];

vector <int> e[N];

void DFS (int u) {
	siz[u] = 1, mini[u] = u, maxi[u] = u;
	for (int it = 0; it < e[u].size(); ++it) {
		int v = e[u][it];
		DFS (v);
		mini[u] = min (mini[u], mini[v]);
		maxi[u] = max (maxi[u], maxi[v]);
		siz[u] += siz[v];
	}
}

int main () {
	scanf ("%d", &n);
	for (int i = 1; i < n; ++i) {
		int u, v;
		scanf ("%d%d", &u, &v);
		e[u].push_back(v);
		c[u]++, r[v]++;
	}
	for (int i = 1; i <= n; ++i) 
		if (r[i] == 0) root = i;
	DFS (root);
	int ans = 0;
	for (int i = 1; i <= n; ++i) 
		if (maxi[i] - mini[i] + 1 == siz[i]) ++ans;
	cout << ans << endl;
	return 0;
}

  

总结:

第一眼看这个题真的是被水淹没,不知所措,但是根据极端情况切入会简单很多QAQ

GDFZOJ 美丽树

标签:namespace   ons   #include   main   cst   代码   algo   space   ++   

原文地址:http://www.cnblogs.com/xgtao/p/5986745.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!