【汕头市选2014】分叉(fork)

来源:互联网 发布:御剑江湖知乎 编辑:程序博客网 时间:2024/04/29 01:16

题目

Description

给出一棵N 个点的树,点的编号是1, 2,。。。,N。

对于3 个点{a,b,c},如果不存在一条简单路径同时经过a,b,c,那么{a,b,c}是一个分叉。

统计不同分叉的数量。

树 无环,连通的无向图

简单路径 不重复经过同一个点的路径

Input

第1 行,1 个整数N。接下来(N -1) 行,每行2 个整数Ai,Bi,表示点Ai 和点Bi 间有一条边。

Output

1 个整数,表示所求的值。

Sample Input

5

1 2

1 3

1 4

1 5

Sample Output

4

Data Constraint

• 对于30% 的数据,N <= 100;

• 对于50% 的数据,N <= 1000;

• 对于100% 的数据,1 <= N <= 10^5。

题解

我们可以反着做,也就是找出合法的{x,y,z}三元组
那么我们可以枚举y,而x和z分别在以y为根形成的树的两颗子树里面,计算每一个y对应的组数,这样就不会有重复的情况了

贴代码

var    a,b:array[0..200005,1..2]of longint;    father,son:array[0..100005]of longint;    size:array[0..100005]of int64;    bz:array[0..100005]of boolean;    i,j,k,l,m,n,x,y,z:longint;    ans,nn,p:int64;procedure qsort(l,r:longint);var    i,j,mid:longint;begin    i:=l;    j:=r;    mid:=a[(i+j) 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            a[0]:=a[i];            a[i]:=a[j];            a[j]:=a[0];            inc(i);            dec(j);        end;    until i>j;    if i<r then qsort(i,r);    if l<j then qsort(l,j);end;procedure star;begin    b[a[1,1],1]:=1;    for i:=2 to k do    if a[i,1]<>a[i-1,1] then    begin        b[a[i-1,1],2]:=i-1;        b[a[i,1],1]:=i;    end;    b[a[k,1],2]:=k;end;procedure dfs(x:longint);var    i:longint;begin    bz[x]:=true;    for i:=b[x,1] to b[x,2] do    if (i<>0) and (bz[a[i,2]]=false) then    begin        father[a[i,2]]:=x;        inc(son[x]);        dfs(a[i,2]);        size[x]:=size[x]+size[a[i,2]];    end;    inc(size[x]);end;begin    //assign(input,'t3.in'); reset(input);    assign(input,'fork.in'); reset(input);    assign(output,'fork.out'); rewrite(output);    readln(n);    for i:=1 to n-1 do    begin        readln(a[i,1],a[i,2]);        a[i+n-1,1]:=a[i,2];        a[i+n-1,2]:=a[i,1];    end;    k:=2*n-2;    qsort(1,k);    star;    dfs(1);    nn:=n;    ans:=trunc(nn*(nn-1)/6*(nn-2));    for i:=1 to n do    if son[i]>0 then    begin        p:=0;        for j:=b[i,1] to b[i,2] do        if a[j,2]<>father[i] then        begin            ans:=ans-size[a[j,2]]*(nn-size[a[j,2]]-1-p);            p:=p+size[a[j,2]];        end;    end;    writeln(ans);    close(input); close(output); end.
0 0
原创粉丝点击