【CF700B】Connecting Universities(贪心,树上最短路)

题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大。

思路:一条边的两侧如果有一侧没有给定的节点就不会被经过……

        如果有1个节点就会被经过1次……

        如果两侧分别有x,y个给定节点就会被经过min(x,y)次

        因为要使总路程最大就是让每一条路被走过最多的次数

        肯定是两侧各取一个 剩下的只能在某侧内部解决

        所以按此统计即可

        答案很大 用INT64

    

 1 var head,vet,next,a,b,c,dep,flag,f:array[1..500000]of longint;
 2     n,k,tot,i:longint;
 3     ans:int64;
 4 
 5 procedure add(a,b:longint);
 6 begin
 7  inc(tot);
 8  next[tot]:=head[a];
 9  vet[tot]:=b;
10  head[a]:=tot;
11 end;
12 
13 function min(x,y:longint):longint;
14 begin
15  if x<y then exit(x);
16  exit(y);
17 end;
18 
19 procedure dfs(u,fa:longint);
20 var e,v:longint;
21 begin
22  flag[u]:=1;
23  e:=head[u];
24  while e<>0 do
25  begin
26   v:=vet[e];
27   if (v<>fa)and(flag[v]=0) then
28   begin
29    dep[v]:=dep[u]+1;
30    dfs(v,u);
31    f[u]:=f[u]+f[v];
32   end;
33   e:=next[e];
34  end;
35 end;
36 
37 begin
38  read(n,k);
39  for i:=1 to 2*k do
40  begin
41   read(c[i]);
42   f[c[i]]:=1;
43  end;
44  for i:=1 to n-1 do
45  begin
46   read(a[i],b[i]);
47   add(a[i],b[i]);
48   add(b[i],a[i]);
49  end;
50  dfs(1,-1);
51  for i:=1 to n-1 do
52   if dep[a[i]]>dep[b[i]] then ans:=ans+min(f[a[i]],2*k-f[a[i]])
53    else ans:=ans+min(f[b[i]],2*k-f[b[i]]);
54  writeln(ans);
55 
56 end.

 

posted on 2016-09-12 20:56  myx12345  阅读(152)  评论(0编辑  收藏  举报

导航