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 }
  • 相关阅读:
    Visual Studio 2010使用Visual Assist X的方法
    SQL Server 2000 评估版 升级到 SQL Server 2000 零售版
    双网卡多网络单主机同时访问
    开发即过程!立此纪念一个IT新名词的诞生
    delphi dxBarManager1 目录遍历 转为RzCheckTree2树
    5320 软件集合
    delphi tree 从一个表复制到另一个表
    DELPHI 排课系统课表
    长沙金思维 出现在GOOGLE的 金思维 相关搜索里啦!!
    如何在DBGrid的每一行前加一个单选框?
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8682123.html
Copyright © 2011-2022 走看看