原題:
https://jzoj.net/senior/#contest/show/2043/0
題目描述:
GDOI商場推出優惠活動,以超低價出售若干種商品。但是,商場為避免過分虧本,規定某些商品不能同時購買,而且每種超低價商品只能買一件。身為顧客的你想獲得最大的實惠,也就是爭取節省最多的錢。經過仔細研究,發現商場出售的超低價商品中,不存在以下情況:
n(n>=3)種商品C1,C2,…..,Cn,其中Ci,Ci+1是不能同時購買的(i=1,2…,n-1)并且C1, Cn也不能同時購買。
編程計算可以節省的最大金額數。
輸入:
第一行兩個整數K,M(1<=K<=1000).其中K表示超低價商品數。K種商品的編號依次為1,2,…,K。M表示不能同時購買的商品對數.接下來K行,第i行有一個整數Xi表示購買編號為i的商品可以節省的金額(1<=Xi<=100).再接下來M行,每行兩個數A ,B,表示A和B不能同時購買,1<=A<=K,1<=B<=K,A<>B
輸出:
僅一個整數,表示能節省的最大金額數。
樣例輸入:
3 1 1 1 1 1 2
樣例輸出:
2
分析:
經典的樹形DP······
實現:
uses math;
var
p,t:array[1..1000,0..500]of longint;
c:array[1..1000]of longint;
v:array[1..1000]of boolean;
f:array[1..2,1..1000]of longint;
n,m,a,b,s,i:longint;
procedure make(x:longint);
var
i:longint;
begin
v[x]:=true;
for i:=1 to p[x,0] do
if not v[p[x,i]] then
begin
t[x,0]:=t[x,0]+1;
t[x,t[x,0]]:=p[x,i];
make(p[x,i]);
end;
end;
procedure dg(x:longint);
var
i:longint;
begin
if t[x,0]=0 then
begin
f[1,x]:=0;
f[2,x]:=c[x];
exit;
end;
for i:=1 to t[x,0] do dg(t[x,i]);
for i:=1 to t[x,0] do
begin
f[1,x]:=f[1,x]+max(f[1,t[x,i]],f[2,t[x,i]]);
f[2,x]:=f[2,x]+f[1,t[x,i]];
end;
f[2,x]:=f[2,x]+c[x];
end;
begin
readln(n,m);
for i:=1 to n do readln(c[i]);
for i:=1 to m do
begin
readln(a,b);
p[a,0]:=p[a,0]+1;p[a,p[a,0]]:=b;
p[b,0]:=p[b,0]+1;p[b,p[b,0]]:=a;
end;
for i:=1 to n do
if p[i,0]=0 then s:=s+c[i]
else
if not v[i] then
begin
make(i);
dg(i);
s:=s+max(f[1,i],f[2,i]);
end;
writeln(s);
end.