【Description】
自从明明学了树的结构,就对奇怪的树产生了兴趣…… 给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间连线,可产生多少棵度数满足要求的树?
【Input】
第一行为N(0 < N < = 1000),接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1
【Output】
一个整数,表示不同的满足要求的树的个数,无解输出0
【Sample Input】
3
1
-1
-1
【Sample Output】
2
【Solution】
Prufer编码。详见:怡红公子
代码如下:
/**************************************************************
Problem: 1005
User: llgyc
Language: Pascal
Result: Accepted
Time:36 ms
Memory:240 kb
****************************************************************/
const mo = 10000;
type HP=array[0..1005] of longint;
var n,m,cnt,tot:longint;
prime,num,d:array[0..1005] of longint;
ans:HP;
function judge(x:longint):boolean;
var i:longint;
begin
for i:=2 to trunc(sqrt(x)) do
if x mod i=0 then exit(false);
exit(true);
end;
procedure prep();
var i:longint;
begin
for i:=2 to 1000 do
if judge(i) then begin inc(cnt); prime[cnt]:=i; end;
ans[0]:=1; ans[1]:=1;
end;
procedure extract(x,p:longint);
var i,j,tmp:longint;
begin
for i:=1 to x do begin
tmp:=i;
for j:=1 to cnt do begin
if tmp<=1 then break;
while (tmp mod prime[j]=0) do begin tmp:=tmp div prime[j]; num[j]:=num[j]+p; end;
end;
end;
end;
procedure print(x:HP);
var i:longint;
begin
write(x[x[0]]);
for i:=x[0]-1 downto 1 do begin
if x[i]<1000 then write(0);
if x[i]<100 then write(0);
if x[i]<10 then write(0);
write(x[i]);
end; writeln;
end;
procedure mul(var a:HP; b:longint);
var c:HP;
i:longint;
begin
fillchar(c,sizeof(c),0);
c[0]:=a[0];
for i:=1 to c[0] do begin
c[i]:=c[i]+a[i]*b;
c[i+1]:=c[i] div mo;
c[i]:=c[i] mod mo;
end;
while (c[c[0]+1]>0) do begin
inc(c[0]); c[c[0]+1]:=c[c[0]] div mo; c[c[0]]:=c[c[0]] mod mo;
end;
a:=c;
end;
procedure main();
var x,i,j:longint;
begin
if n=1 then begin
readln(x);
if x=0 then writeln(1) else writeln(0);
exit;
end;
for i:=1 to n do begin
readln(d[i]);
if d[i]=0 then begin writeln(0); exit; end;
if d[i]=-1
then inc(m)
else begin dec(d[i]); inc(tot,d[i]); end;
end;
if tot>n-2 then begin writeln(0); exit; end;
fillchar(num,sizeof(num),0);
extract(n-2,1); extract(n-2-tot,-1); for i:=1 to n do if d[i]>0 then extract(d[i],-1);
for i:=1 to cnt do
for j:=1 to num[i] do mul(ans,prime[i]);
for i:=1 to n-2-tot do mul(ans,m);
print(ans);
end;
begin
prep();
readln(n);
main();
end.