UVAlive 3092 无根树->有根树 dfs

原创 2016年08月29日 10:19:24

题目链接:UVALA 3092


题意:给定一个无根树,选其中一个非叶子节点作为服务器, 求要放置最小的服务器数满足 每个叶子节点到最近的服务器的距离最大为k,且服务器只能放在非叶子节点上。




题解:先用dfs把无根树转成以给定服务器为根节点的有根树,那么 深度d <= k的叶子节点就可以不用考虑了,然后 对于 深度大于k的叶子节点  最优解就是 把 服务器设在 他k级祖先上(k倍父节点),然后选择完服务器用dfs覆盖距离这个节点距离k之内的可达叶子节点,直至所有叶子节点均被访问。


AC code:

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

#define debug 0
#define M(a, b) memset(a, b, sizeof(a))

const int maxn = 1000 + 5;

vector<int> gr[maxn], node[maxn];
int n, s, k;
int fa[maxn];
bool vis[maxn];

void dfs(int u, int f, int d) {										//建树
	fa[u] = f;
	int nc = gr[u].size();
	if (nc == 1 && d > k)											//深度大于k叶子节点,记录下来 
		node[d].push_back(u);
	for (int i = 0; i < nc; i++) {
		int v = gr[u][i];
		if (v != f) {												//因为子结点的vector容器内也有父节点,所以这个判断不能省
			dfs(v, u, d + 1);
		}
	}
}
void dfs2(int u, int f, int d) {
	vis[u] = 1;														//标为已访问表示 改点已被覆盖
	int nc = gr[u].size();											//找到服务器 递归覆盖
	/*if (n == 1 && d > k)
		node[d].push_back(u);*/
	for (int i = 0; i < nc; i++) {
		int v = gr[u][i];
		if (v != f && d < k) {										//覆盖范围最大为k
			dfs2(v, u, d + 1);										//递归
		}
	}
}
int solve() {
	int ans = 0;
	for (int d = n - 1; d > k; d--) {								//枚举深度大于k的叶子节点
		for (int i = 0; i < node[d].size(); i++)		
		{			
			int v = node[d][i];
			if (!vis[v]) {											//未被覆盖
				for (int i = 1; i <= k; i++) {					
					v = fa[v];										//找k级祖先
				}
				dfs2(v, -1, 0);					
				ans++;				
			}
		}
	}
		return ans;
}
int main() {
#if debug
	freopen("in.txt", "r", stdin);
#endif //debug

	int t, a, b;
	scanf("%d", &t);
	while (t--) {

		M(fa, 0);
		M(vis, 0);	
		scanf("%d%d%d", &n, &s, &k);
		for (int i = 1; i <= n; i++) {
			gr[i].clear();
			node[i].clear();												//初始化
		}

		for (int i = 1; i < n; i++) {
			scanf("%d%d", &a, &b);
			gr[a].push_back(b);
			gr[b].push_back(a);
		}

		dfs(s, -1, 0);														//递归建树
		//printf("1");

		printf("%d\n", solve());
	}


	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

uva1267(无根树 +dfs)

题意: 在一张图中,有n个点,要建几个服务站,服务站可以服务离他距离为k的点;一开始只有一个服务站; 现在给出有几组样例,每组样例给出有n个点,最开始的服务站位置start,还有服务站的服务距离d...

uva1267 - Network 无根树转化有根树 树形DFS

Consider a tree network with n nodes where the internal nodes correspond to servers and the terminal...
  • corncsd
  • corncsd
  • 2014年01月30日 14:22
  • 489

【学术篇】oj.jzxx.net2701 无根树

这是一道来自OIerBBS的题目.. 原帖地址:http://www.oierbbs.com/forum.php?mod=viewthread&tid=512?fromuid=71 (似乎是个很小...
  • Enzymii
  • Enzymii
  • 2017年03月24日 09:51
  • 870

hdoj 4009 Transfer water 【求无根树最小树形图】

Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) T...

无根树转换成为有根树

/* 以前和大家说的都是二叉树,有一种更广义的,就是树,树可以有不仅仅两个子树, 其实树和图没有多少差别,树都可以用图的表示方法来表示,就比如邻接矩阵和邻接表来表示树,都是可以的, 今天给大家介...

nyoj20 吝啬的国度 (无根树转换为实根树)

题目20 题目信息 运行结果 本题排行 讨论区 吝啬的国度 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述在一个吝...

hdoj 2121 Ice_cream’s world II 【虚拟源点求无根树的最小树形图】

Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth...

Codeforces Round #408 (Div. 2) C. Bank Hacking 无根树、贪心、枚举

题意:有一棵无根树,上面每个节点都有一个权值,可以任意选择一个节点删除,但这是和它相邻的节点即隔一个点间接相邻的点 的权值都会增加1,求把所有的点都依次删除,中途会遇到的最大权值点的 最小权值。 无根...

codeforce 796C - Bank Hacking(无根树+思维)

Although Inzane successfully found his beloved bone, Zane, his owner, has yet to return. To search f...

【HDU5732 2016 Multi-University Training Contest 1J】【树哈希模板 无根树的同构】Subway 对应两棵树的匹配关系

Subway Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVAlive 3092 无根树->有根树 dfs
举报原因:
原因补充:

(最多只允许输入30个字)