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...

树的同构--poj 1635(有根树)ustc 1117 (无根树)

只有一个点入度为0的树是外向树,只有一个点出度为0的树是内向树,这两种是典型的有根树 平时见到的无向图中的树是无根树 1.判断树同构本质是哈希,每个点的权值是这个点的子树的权值和,这里所谓的权值是随机...

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...

NYOJ - 20 - 吝啬的国度(无根树转有根树)

描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来。现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号城市(假设...

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

这是一道来自OIerBBS的题目.. 原帖地址:http://www.oierbbs.com/forum.php?mod=viewthread&tid=512?fromuid=71 (似乎是个很小...

无根树转换成为有根树

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

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

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

UVALive 4815 || SYSU 2387 Kids' Wishes dfs+(字典树哈希)

传送门:题源较多,大家可以到BNU上搜下Kid's Wishes。 提议:有还多孩子,和很多愿望,每个愿望有2个数字,代表前一个编号的孩子和后一个坐相邻,问所有愿望实现,能都坐成一个圈。 思路:虽...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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