zoukankan      html  css  js  c++  java
  • luogu3942 将军令 贪心

    题目大意:给你一个地图(树),共有1~n个驿站(点),编号分别为1~n,告诉你第ui个驿站与第vi个驿站有一条长度为1的路(边),每个小队(可以放在任意驿站上)最多有k的覆盖长度,问最多要放置多少个小队才能把整张图全部覆盖?

    把一个驿站当作市中心(树根),显然离市中心越偏远(深度越深)的驿站就越难被控制,所以我们优先考虑深度最深的节点。用来控制深度最深的节点v的小队应当布置在能控制到v且离v最远的节点u上,这样顺带着控制到的节点是最多的。所以具体操作为:将节点按照深度从大到小排序,判断是否覆盖过,如果没覆盖过,找其k级父亲并覆盖其周围距离不超过k的所有节点。这种方法没有后效性,因为选了一个节点不会导致其它节点不能选。

    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <algorithm>
    #include <cstdarg>
    using namespace std;
    
    const int MAX_NODE = 100010;
    int K;
    
    void _printf(const char *format, ...)
    {
    #ifdef _DEBUG
    	//va_list(args);
    	//va_start(args, format);
    	//vprintf(format, args);
    	//va_end(args);
    #endif
    }
    
    struct Node
    {
    	int Id;
    	int Depth;
    	Node *Fa;
    	vector<Node*> Next;
    	bool Ctrled;
    }_nodes[MAX_NODE], *Root, *Order[MAX_NODE];
    int TotNode;
    
    void AddEdge(int uId, int vId)
    {
    	Node *u = _nodes + uId, *v = _nodes + vId;
    	u->Id = uId, v->Id = vId;
    	u->Next.push_back(v);
    	v->Next.push_back(u);
    }
    
    void Read()
    {
    	int t, u, v;
    	scanf("%d%d%d", &TotNode, &K, &t);
    	for (int i = 1; i <= TotNode - 1; i++)
    	{
    		scanf("%d%d", &u, &v);
    		AddEdge(u, v);
    	}
    }
    
    void Init_Dfs(Node *cur, Node *fa, int depth)
    {
    	cur->Depth = depth;
    	cur->Fa = fa;
    	_printf("%d->%d depth %d
    ", fa?fa->Id:0, cur->Id, cur->Depth);
    	int len = cur->Next.size();
    	for (int i = 0; i < len; i++)
    		if (cur->Next[i] != fa)
    			Init_Dfs(cur->Next[i], cur, depth + 1);
    }
    
    void SetDepth()
    {
    	Root = _nodes + 1;
    	Init_Dfs(Root, NULL, 1);
    }
    
    bool Cmp_Depth(Node *a, Node *b)
    {
    	return a->Depth > b->Depth;
    }
    
    void SetOrder()
    {
    	for (int i = 1; i <= TotNode; i++)
    		Order[i] = _nodes + i;
    	sort(Order + 1, Order + TotNode + 1, Cmp_Depth);
    }
    
    void SetCtrl_Dfs(Node *fa, Node *cur, int k)
    {
    	_printf("ctrled %d
    ", cur->Id);
    	cur->Ctrled = true;
    	int len = cur->Next.size();
    	if (k < K)
    		for (int i = 0; i < len; i++)
    			if (cur->Next[i] != fa)
    				SetCtrl_Dfs(cur, cur->Next[i], k + 1);
    }
    
    int SetCtrl()
    {
    	int ans = 0;
    	for (int i = 1; i <= TotNode; i++)
    	{
    		Node *cur = Order[i];
    		if (!cur->Ctrled)
    		{
    			_printf("deepest %d ", cur->Id);
    			ans++;
    			for (int j = 1; j <= K && cur->Fa; j++)
    				cur = cur->Fa;
    			_printf("lighted %d
    ", cur->Id);
    			SetCtrl_Dfs(NULL, cur, 0);
    		}
    	}
    	return ans;
    }
    
    int main()
    {
    	Read();
    	SetDepth();
    	SetOrder();
    	printf("%d
    ", SetCtrl());
    	return 0;
    }
    

      

  • 相关阅读:
    pr 打印函数
    list to tree(记录集转换为树结构)
    iOS 中计时器的使用心得
    iOS动画开发----打分 数字滚动刷新动画
    iOS动画开发----粒子系统---彩带效果
    Touch Up Inside not working with UISlider
    Xcode警告:Automatic Preferred Max Layout Width is not available on iOS versions prior to 8.0
    iOS评论App----常用时间的处理
    获取文件/文件系统属性的方法----attributesOfItemAtPath:和attributesOfFileSystemForPath:
    NSInvocation错误
  • 原文地址:https://www.cnblogs.com/headboy2002/p/8996205.html
Copyright © 2011-2022 走看看