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

    题目描述

    又想起了四月。

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

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

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

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

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

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

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

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

    输入输出格式

    输入格式:

    从标准输入中读入数据。

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

    输入第 2 行至第 n 行,每行两个正整数 u_iui,v_ivi,表示在 u_iui 和 v_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。

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

    代码

    贪心

    每次从深度最大的节点开始覆盖距离为k的祖先

    找祖先可以直接暴力,如果k再大一点。

    可以考虑倍增,当然这题没必要

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    const int maxn=1e5+10;
    int head[maxn],dis[maxn];
    int s[maxn];
    int inq[maxn],vis[maxn],fa[maxn];
    int size=0,tot=0;
    struct edge
    {
        int to,next;
    }e[maxn<<1];
    int ans=0;
    int n,k;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
        return x*f;
    }
    void addedge(int u,int v)
    {
        e[++size].to=v;e[size].next=head[u];head[u]=size;
    }
    void bfs(int u)
    {
        queue<int>q;
        q.push(u);
        s[++tot]=u;
        inq[u]=1;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            for(int i=head[u];i;i=e[i].next)
            { 
            int to=e[i].to;
            if(inq[to])continue;
            dis[to]=dis[u]+1;
            if(!inq[to])
            q.push(to),fa[to]=u,s[++tot]=to,inq[to]=1;
            }
        }
    
    }
    void dfs(int u,int fa,int d)
    {
        if(d>k)return;
        vis[u]=1;
        for(int i=head[u];i;i=e[i].next)
        {
            int to=e[i].to;
            if(to==fa)continue;
            dfs(to,u,d+1);
        }
    }
    
    int main()
    {
        memset(dis,-inf,sizeof(dis));
        n=read(),k=read(),read();
        for(int i=2;i<=n;i++)
        {
            int u=read(),v=read();
            addedge(u,v);addedge(v,u);
        }
        bfs(1);
        for(int i=tot;i;i--)
        {
            int x=s[i];
            if(vis[x])continue;
            ans++;
            for(int i=1;i<=k;i++)
            x=fa[x];
            dfs(x,0,0);
        }
        printf("%d",ans);
        return 0;
    } 
    View Code
  • 相关阅读:
    PAT顶级 1015 Letter-moving Game (35分)
    PAT顶级 1008 Airline Routes (35分)(有向图的强连通分量)
    PAT顶级 1025 Keep at Most 100 Characters (35分)
    PAT顶级 1027 Larry and Inversions (35分)(树状数组)
    PAT 顶级 1026 String of Colorful Beads (35分)(尺取法)
    PAT顶级 1009 Triple Inversions (35分)(树状数组)
    Codeforces 1283F DIY Garland
    Codeforces Round #438 A. Bark to Unlock
    Codeforces Round #437 E. Buy Low Sell High
    Codeforces Round #437 C. Ordering Pizza
  • 原文地址:https://www.cnblogs.com/DriverBen/p/11002489.html
Copyright © 2011-2022 走看看