noip2014联合权值

原文链接:http://www.cnblogs.com/cxvdzxhb/p/4510452.html

http://codevs.cn/problem/3728/

我们要做的是计算距离为2的有序对权值之和及最大值,最大值好弄,但一一枚举是不可行的,因为n<=200000,我们可以预处理一下,每次读入边的时候我们把与当前顶点有边相连的所有点的权值中的最大值及次大值保存起来,然后用个O(n)时间就可以计算出来。至于权值和,我们可以这样,用s[i]存储与节点i相连的节点的权值和,枚举每条边(u,v),sigma((s[u]-w[v])*w[v]+(s[v]-w[u])*w[u])mod 1007 即是答案。

 

 

type
  edge=record
    u,v:longint;
  end;
var
 n,i,j,ans1,ans2,u,v:longint;
 s:array[1..200000]of int64;
 w,max1,max2:array[1..200000]of longint;
 e:array[1..200000]of edge;
procedure work(x:longint;var a,b:longint);
begin
  if x>a then 
  begin
    b:=a; a:=x;
  end
    else
  if x>b then b:=x;
end;
begin
  readln(n);
  for i:=1 to n-1 do readln(e[i].u,e[i].v);
  for i:=1 to n do read(w[i]);
  for i:=1 to n-1 do 
  begin 
    u:=e[i].u; v:=e[i].v;
    inc(s[u],w[v]);
    inc(s[v],w[u]);
    work(w[v],max1[u],max2[u]);
    work(w[u],max1[v],max2[v]);
  end;
  for i:=1 to n do if max1[i]*max2[i]>ans1 then ans1:=max1[i]*max2[i];
  for i:=1 to n-1 do
  begin
    u:=e[i].u; v:=e[i].v;
    ans2:=(ans2+(s[u]-w[v])*w[v] mod 10007)mod 10007;
    ans2:=(ans2+(s[v]-w[u])*w[u] mod 10007)mod 10007;
  end;
  writeln(ans1,' ',ans2);
end.

 

 

转载于:https://www.cnblogs.com/cxvdzxhb/p/4510452.html

上一篇:【JZOJ 3858】【NOIP2014八校联考第3场第2试10.5】挖掘机技术哪家强


下一篇:MFC覆盖OnPrepareDC实现“所见即所得”打印