zoukankan      html  css  js  c++  java
  • bzoj 1517 [POI2006]Met 贪心

    [POI2006]Met

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 203  Solved: 108
    [Submit][Status][Discuss]

    Description

    给出一棵N个结点的树,选择L条路径,覆盖这些路径上的结点,使得被覆盖到的结点数最多。

    Input

    第一行两个正整数N、L(2 <= N <= 1,000,000, 0 <= L <= N)。下面有N-1行,每行两个正整数A和B(1 <= A, B <= N),表示一条边(A,B)。

    Output

    一个整数,表示最多能覆盖到多少结点。

    Sample Input

    17 3
    1 2
    3 2
    2 4
    5 2
    5 6
    5 8
    7 8
    9 8
    5 10
    10 13
    13 14
    10 12
    12 11
    15 17
    15 16
    15 10

    Sample Output

    13

    HINT

    鸣谢Oimaster

    Source

     选择路径的代价相同显然考虑贪心。 
    首先我们可以按照拓扑关系把原图分层。 
    接下来我们考虑,对于每一层来说,我们显然最多选取2*l个点。 
    我们最终选的路径一定是l对叶子节点到另一个叶子节点异或是都选。 
    又每一个叶子节点一定由上一层的来,所以选叶子节点的话一定会覆盖其他层的点。 
    =-=噫 
    我知道我说的好乱。 
    结论是什么呢? 
    对于每一层来说,对答案的贡献是min(2*l,num[dep]) 
    num[dep]代表第dep层的节点个数。 
    求和即可。 
     
     1 #include <queue>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 #define N 1000100
     7 using namespace std;
     8 int head[N],cnt;
     9 int n,l;
    10 int in[N];
    11 int dep[N];
    12 int sum[N];
    13 struct node
    14 {
    15     int from,to,next;
    16 }edge[N<<1];
    17 void init()
    18 {
    19     memset(head,-1,sizeof(head));
    20     cnt=1;
    21 }
    22 void edgeadd(int from,int to)
    23 {
    24     edge[cnt].from=from,edge[cnt].to=to,edge[cnt].next=head[from];
    25     head[from]=cnt++;
    26 }
    27 void topsort()
    28 {
    29     queue<int>q;
    30     for(int i=1;i<=n;i++)
    31     {
    32         if(in[i]==1)
    33             dep[i]=1,q.push(i),sum[1]++;
    34     }
    35     while(!q.empty())
    36     {
    37         int u=q.front();
    38         q.pop();
    39         for(int i=head[u];i!=-1;i=edge[i].next)
    40         {
    41             int to=edge[i].to;
    42             in[to]--;
    43             if(in[to]==1)
    44             {
    45                 dep[to]=dep[u]+1;
    46                 sum[dep[to]]++;
    47                 q.push(to);
    48             }
    49         }
    50     }
    51     int ans=0;
    52     for(int i=1;sum[i];i++)
    53     {
    54         ans+=min(sum[i],2*l);
    55     }
    56     printf("%d
    ",ans);
    57 }
    58 int main()
    59 {
    60     init();
    61     scanf("%d%d",&n,&l);
    62     for(int i=1;i<n;i++)
    63     {
    64         int x,y;
    65         scanf("%d%d",&x,&y);
    66         edgeadd(x,y);
    67         edgeadd(y,x);
    68         in[x]++,in[y]++;
    69     }
    70     topsort();
    71 }
  • 相关阅读:
    debian 9 安装AMD驱动
    DDL、DML、DCL、DQL的理解
    呼叫中心坐席功能都有哪些?
    使用vi编辑器的问题
    百度聊天机器人UNIT http访问
    通过http方式 post天气,并合成语音
    单链表的基本操作
    pip下载慢解决(添加国内镜像)
    Anaconda+Tensorflow配置说明
    gdb的基本使用
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682123.html
Copyright © 2011-2022 走看看