【问题描述】
月考刚考了年级倒数的敌敌来到电脑室,朝着正在写树套树套树套树的beginend大吼:我就不信我有辣么辣鸡!我可是去年普及组AC了第一题的人啊!
beginend不耐烦地扔了一道题给敌敌,然后说:你只要把这道题写出来你就不是辣鸡啦。
敌敌接过题一看,题目是这样的:
有n个点和n-1条无向边,满足任意两点都可以互相到达,求有多少条经过且仅经过三个点的简单路径。
(简单路径即为每个点最多被访问一次的路径)
但是敌敌发现自己并不会写这题,但又不愿承认自己是辣鸡这个事实,于是他就拿着题目来找刚刚成为保送狗的你。为了敌敌的智商,你只好选择了帮他一把。
【输入格式】
第一行一个正整数n表示城市数量。
接下来n-1行每行两个正整数u,v表示u和v之间有一条道路。
【输出格式】
输出一行,表示经过且仅经过三个点的简单路径的数量。
【题解】
暴力!
【代码】
var
ans:int64;
n:longint;
f,sum:array [0..200001] of longint;
a:array [0..400001,1..2] of longint;
procedure init;
var
i,x,y:longint;
begin
readln(n);
for i:=1 to n-1 do
begin
readln(x,y);
a[i,1]:=x; a[i,2]:=y;
a[n+i-1,1]:=y; a[n+i-1,2]:=x;
inc(f[x]); inc(f[y]);
end;
ans:=0;
end;
procedure qsort(l,r:longint);
var
i,j,mid,t:longint;
begin
if l>r then exit;
i:=l; j:=r;
mid:=a[(l+r) div 2,1];
repeat
while a[i,1]<mid do inc(i);
while a[j,1]>mid do dec(j);
if i<=j then
begin
t:=a[i,1]; a[i,1]:=a[j,1]; a[j,1]:=t;
t:=a[i,2]; a[i,2]:=a[j,2]; a[j,2]:=t;
inc(i); dec(j);
end;
until i>j;
qsort(i,r);
qsort(l,j);
end;
procedure main;
var
i,j:longint;
begin
fillchar(sum,sizeof(sum),0);
sum[1]:=1;
for i:=2 to n do
sum[i]:=f[i-1]+sum[i-1];
sum[n+1]:=sum[n]+1;
for i:=1 to n do
for j:=sum[i] to sum[i+1]-1 do
ans:=ans+f[a[j,2]]-1;
write(ans);
end;
begin
assign(input,'didi.in');
assign(output,'didi.out');
reset(input);
rewrite(output);
init;
qsort(1,n*2-2);
main;
close(input);
close(output);
end.