BZOJ 1785 [Usaco2010 Jan]telephone

Description

奶牛们建立了电话网络,这个网络可看作为是一棵无根树连接n(1 n 100,000)个节点,节点编号为1 .. n。每个节点可能是(电话交换机,或者电话机)。每条电话线连接两个节点。第i条电话线连接两个节点Ai和Bi(1 Ai,Bi n; Ai Bi)。叶子节点只连接一条电话线,这些叶子节点是位于电话网中的一个电话亭。两头奶牛需要通话,信号是沿着电话网络中连接两个顶点之间最短的路径传递。每部交换机最多可容纳K (1 K 10)对牛同时通话,对于输入的无根树,求出在任何一个时间最多可同时对话奶牛的对数。下面是6个节点的电话网络(无根树): 在叶子节点1,3,5和6中有四头奶牛,如果奶牛1和奶牛3,奶牛5和奶牛6通话,那么同时通话的最大数目是2(2对奶牛同时通话)。

Input

第1行: 用空格分开的两个整数:n和k。第2..n+1行: 第i+1行用空格分开的两个整数,Ai和Bi。

Output

仅1行: 一个整数表示可同时对话奶牛的对数。

Sample Input

6 1
1 2
2 3
2 4
4 5
4 6

Sample Output

2
只要能推出贪心的方法,这道题并不难。
首先尽量在树内配对,因为让一个点与树外的点配对花费的代价更大。
其次只要把树内剩下的点与树外的配对好即可。
代码如下:
var
g:array[0..100000]of boolean;
pre,son:array[0..200000]of longint;
f,now:array[0..100000]of longint;
p,ans,tot,max,root,n,m,i,j,k:longint;
procedure insert(a,b:longint);
begin
  inc(tot);
  pre[tot]:=now[a];
  now[a]:=tot;
  son[tot]:=b;
end;

procedure dfs(x,fa:longint);
var
k,p:longint;
begin
p:=now[x];
if pre[p]=0 then
  begin
    g[x]:=true;
    if x<>1 then
    exit;
  end;
while p<>0 do
  begin
    if son[p]<>fa then
      begin
        dfs(son[p],x);
        if g[son[p]] then
          if g[x] then
             begin
               inc(f[x]);
               g[x]:=false;
             end
          else
            if f[x]<>max then
              g[x]:=true;
      end;
      p:=pre[p];
  end;
ans:=ans+f[x];
end;

begin
ans:=0;
readln(n,max);
for i:=1 to n-1 do
  begin
    readln(j,k);
    insert(j,k);
    insert(k,j);
  end;
dfs(1,0);
writeln(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值