zoukankan      html  css  js  c++  java
  • P3942 将军令

    题目背景

    pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv

     历史/落在/赢家/之手 
     至少/我们/拥有/传说 
     谁说/败者/无法/不朽 
     拳头/只能/让人/低头 
     念头/却能/让人/抬头 
     抬头/去看/去爱/去追 
     你心中的梦   

    题目描述

    又想起了四月。

    如果不是省选,大家大概不会这么轻易地分道扬镳吧? 只见一个又一个昔日的队友离开了机房。

    凭君莫话封侯事,一将功成万骨枯。

    梦里,小 F 成了一个给将军送密信的信使。

    现在,有两封关乎国家生死的密信需要送到前线大将军帐下,路途凶险,时间紧迫。小 F 不因为自己的祸福而避趋之,勇敢地承担了这个任务。

    不过,小 F 实在是太粗心了,他一不小心把两封密信中的一封给弄掉了。

    小 F 偷偷打开了剩下的那封密信。他 发现一副十分详细的地图,以及几句批文——原来 这是战场周围的情报地图。他仔细看后发现,在这张地图上标记了 n 个从 1 到 n 标号的 驿站,n − 1 条长度为 1 里的小道,每条小道双向连接两个不同的驿站,并且驿站之间可以 通过小道两两可达。

    小 F 仔细辨认着上面的批注,突然明白了丢失的信的内容了。原来,每个驿站都可以驻 扎一个小队,每个小队可以控制距离不超过 k 里的驿站。如果有驿站没被控制,就容易产 生危险——因此这种情况应该完全避免。而那封丢失的密信里,就装着朝廷数学重臣留下的 精妙的排布方案,也就是用了最少的小队来控制所有驿站。

    小 F 知道,如果能计算出最优方案的话,也许他就能够将功赎过,免于死罪。他找到了 你,你能帮帮他吗? 当然,小 F 在等待你的支援的过程中,也许已经从图上观察出了一些可能会比较有用的 性质,他会通过一种特殊的方式告诉你。

    输入输出格式

    输入格式:

    从标准输入中读入数据。

    输入第 1 行一个正整数 n,k,t,代表驿站数,一支小队能够控制的最远距离,以及特 殊性质所代表的编号。关于特殊性质请参照数据范围。

    输入第 2 行至第 n 行,每行两个正整数 uiu_iui ,viv_ivi ,表示在 uiu_iuiviv_ivi 间,有一条长度为 一里的小道。

    输出格式:

    输出到标准输出中。

    输出一行,为最优方案下需要的小队数。

    输入输出样例

    输入样例#1: 
    4 1 0 
    1 2 
    1 3 
    1 4
    输出样例#1: 
    1 
     
    输入样例#2: 
    6 1 0 
    1 2 
    1 3 
    1 4 
    4 5 
    4 6
    输出样例#2: 
    2 
    

    说明

    【样例 1 说明】

    如图。由于一号节点到周围的点距离均是 1,因此可以控制所有驿站。

    【样例 2 说明】

    如图,和样例 1 类似。

    子任务会给出部分测试数据的特点。如果你在解决题目中遇到了困难,可以尝试只解 决一部分测试数据。

    关于 t 的含义如下: t = 0:该测试点没有额外的特殊性质; t = 1:保证最多 8 个点的所连接的小道超过 1 条; t = 2:保证所有点到 1 号点的距离不超过 2。

    每个测试点的数据规模及特点如下表

    Solution:

      思路是贪心+搜索。

      因为本题我们并不需要知道具体在哪个点放置军队(可能存在多种方案),而只关心军队数目(显然即使多种方案,最少数目也是一定的),于是就能想到贪心,从最远的点找链长为$2k$的链上的点均打上标记(即处理某个点能控制的最大范围)。

      实现时,首先我们第一遍$dfs1$处理出以$1$为根节点到各个节点的深度$dis$,然后将这$n$个节点以$dis$值从大到小排序。

      然后,从深度最深的没有被$vis2$标记的点(即没有被控制的点)开始$dfs2$处理出从某个点控制该节点的同时能控制的节点,将这些点标记为$vis1$(因为无向,标记后防止被重复询问),同时标记$vis2$表示该点被控制,显然$dfs2$的次数即答案。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    using namespace std;
    const int N=1e5+7;
    int n,k,t,h[N],to[N<<1],net[N<<1],cnt,tot,ans;
    struct point{
        int id,dis;
        bool operator<(const point a) const{
            if(this->dis == a.dis)return this->id < a.id;
            return this->dis < a.dis;
        }
    }a[N];
    bool vis1[N],vis2[N];
    il int gi(){
        int a=0;char x=getchar();bool f=0;
        while((x<'0'||x>'9')&&x!='-')x=getchar();
        if(x=='-')x=getchar(),f=1;
        while(x>='0'&&x<='9')a=a*10+x-48,x=getchar();
        return f?-a:a;
    }
    il void add(int u,int v){
        to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;
        to[++cnt]=u,net[cnt]=h[v],h[v]=cnt;
    }
    il void dfs1(int u,int last){
        for(int i=h[u];i;i=net[i]){
            if(last!=to[i]){
                a[to[i]].dis=a[u].dis+1;
                a[to[i]].id=to[i];
                dfs1(to[i],u);
            }
        }
    }
    il void dfs2(int u,int sum){
        if(sum<0)return;
        vis1[u]=1,vis2[u]=1;
        for(int i=h[u];i;i=net[i])
            if(!vis1[to[i]])dfs2(to[i],sum-1);
        vis1[u]=0;
    }
    int main()
    {
        n=gi(),k=gi(),t=gi();
        int u,v;
        for(int i=1;i<n;i++)u=gi(),v=gi(),add(u,v);
        a[1].dis=0,a[1].id=1;
        dfs1(1,0);
        sort(a+1,a+n+1);
        for(int i=n;i;i--){
            if(!vis2[a[i].id]){
                dfs2(a[i].id,k<<1);
                ans++;
            }
        }
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Thinkph5——模型软删除
    ThinkPHP5——URL参数带中文,报"模块不存在"
    ThinkPHP5多模板配置二级域名
    使用Composer安装阿里云短信失败
    GIT快速入门
    Python全栈之路系列----之-----面向对象4(接口与抽象,多继承与多态)
    Python全栈之路系列----之-----面向对象3(继承与派生)
    Python全栈之路系列----之-----面向对象1(初识)
    Python全栈之路系列----之-----异常处理
    Python全栈之路系列----之-----内置函数和匿名函数lamdba
  • 原文地址:https://www.cnblogs.com/five20/p/8854700.html
Copyright © 2011-2022 走看看