题解

72 条题解

  • 0
    @ 2008-10-07 14:19:00

    向大牛们咨询一个问题:这道题怎么就不存在有一个点是有2个入度呢?

    我都服了,比赛的时候本来向用朴素写一个,但是考虑到有可能有这种情况,所以就直接写了一个FLOYD,结果过了2个。

    • @ 2015-07-03 20:30:17

      树结构不会的吧

  • 0
    @ 2008-10-06 20:22:01

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 134ms

    ├ 测试数据 07:运行时错误...| 错误号: 202 | 堆栈溢出错

    ├ 测试数据 08:答案正确... 462ms

    ├ 测试数据 09:答案正确... 509ms

    ├ 测试数据 10:运行时错误...| 错误号: 202 | 堆栈溢出错

    var

    z:int64;

    h,v,g:array[1..20004]of int64;

    s:array[1..20004,1..3]of int64;

    a,b,c,n,m,i,j,t,q:longint;

    procedure dfs(l1,l2:longint);

    var

    k,i,l3:longint;

    begin

    k:=l1;

    i:=0;

    repeat

    {while u

  • 0
    @ 2008-10-06 12:00:53

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:答案正确... 0ms

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    不用非递归也能全0ms啊。数组模拟链表+dfs,结束时间戳f的等号不能掉啊,害的我一直wa,还有结果和距离要用int64。

  • 0
    @ 2008-10-05 20:26:53

    var

    n,i,u,v:0..10000;

    m,j:0..100000;

    fathers:array[0..10000]of 0..10000;

    times:array[0..10000]of dword;

    time,father,sum,sumtime:int64;

    could:boolean;

    begin

    readln(n,m);

    for i:=1 to n-1 do

    begin

    read(time,father);

    fathers[father]:=time;

    readln(time);

    times[father]:=time

    end;

    sumtime:=0;

    sum:=0;

    for j:=1 to m do

    begin

    readln(u,v);

    father:=v;

    time:=0;

    could:=true;

    while (fatheru) do

    begin

    time:=time+times[father];

    father:=fathers[father];

    if (father=1) and(u1) then begin could:=false; break end;

    end;

    if could then begin sum:=sum+1; sumtime:=sumtime+time end;

    end;

    writeln(sum);

    writeln(sumtime);

    end.

    有谁帮我看看。

    思路:记录每个节点的父节点(fathers)和到父节点的时间(times);

    从最低点(v)搜索,如果最高点是它的父节点(u),那么,记录时间,退出;

    如果搜到底(第一个点)还没有结果,就退出。

    但有若干个点运行超时...

    谁能帮我?

  • 0
    @ 2008-10-03 22:23:31

    正确的0S出解的方法是:

    先用邻接表记录父子关系,然后遍历整棵树,用一个数组BIN记录第一次遍历到某个接点的时间T,用EN数组记录最后一次遍历到某个接点的时间T(即遍历完该接点的所有子接点后返回该接点的时刻),这种方法即称为时间戳,可以用来判断A是否可以到达B..判断的依据是(BIN[A]=EN)TRUE 则可以到达.

    注意遍历要用非递归写,因为N最大有10000,意味着程序最多可能搜10000层,这对评测机是吃不消的... 看来DFS的非递归也很重要啊!

  • 0
    @ 2008-10-03 18:34:03

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ├ 测试数据 05:答案正确... 0ms

    ├ 测试数据 06:答案正确... 0ms

    ├ 测试数据 07:运行时错误...| 错误号: 202 | 堆栈溢出错

    ├ 测试数据 08:答案正确... 0ms

    ├ 测试数据 09:答案正确... 0ms

    ├ 测试数据 10:运行时错误...| 错误号: 202 | 堆栈溢出错

    怎么回事?

    program rally;

    type

    link=^rec;

    rec=record

    w:longint;

    next:link;

    end;

    var

    a,b:array[1..10000]of link;

    f,fa,c,d:array[0..10000]of longint;

    root,n,m,i,k,u,vv,t,way:longint;

    ans,sum:qword;

    v:array[1..10000]of boolean;

    p:link;

    function find(x:longint):longint;

    begin

    if f[x]x then f[x]:=find(f[x]);

    exit(f[x]);

    end;

    function dist(x,y:longint):qword;

    begin

    {writeln(x,' ',y);

    writeln(d[x],' ',d[y]);}

    dist:=d[x]-d[y];

    end;

    procedure search(x:longint);

    var g,h:longint;

    p:link;

    begin

    v[x]:=true; p:=b[x];

    while pnil do

    begin

    if v[p^.w] then

    begin

    h:=find(p^.w);

    if h=p^.w then

    begin inc(sum); inc(ans,dist(x,p^.w)); end;

    end;

    p:=p^.next;

    end;

    f[x]:=x; p:=a[x];

    while pnil do

    begin

    search(p^.w);

    p:=p^.next;

    end;

    f[x]:=fa[x];

    end;

    procedure dfs(x:longint);

    var p:link;

    begin

    p:=a[x];

    while pnil do

    begin

    d[p^.w]:=d[x]+c[p^.w];

    dfs(p^.w);

    p:=p^.next;

    end;

    end;

    begin

    assign(input,'rally.in'); reset(input);

    assign(output,'rally.out'); rewrite(output);

    readln(n,m);

    fillchar(v,sizeof(v),0);

    for i:=1 to n-1 do

    begin

    readln(u,vv,t); v[vv]:=true;

    fa[vv]:=u; c[vv]:=t;

    new(p); p^.w:=vv;

    p^.next:=a; a:=p;

    end;

    for i:=1 to n do

    if not v[i] then

    begin root:=i; break; end;

    fillchar(v,sizeof(v),0);

    for i:=1 to m do

    begin

    readln(u,vv);

    new(p); p^.w:=u;

    p^.next:=b[vv]; b[vv]:=p;

    end;

    ans:=0; sum:=0; way:=0; d[root]:=0;

    dfs(root);

    search(root);

    writeln(sum); writeln(ans);

    close(input); close(output);

    end.

  • 0
    @ 2008-10-03 17:45:51

    用邻接表好做但是只能针对现有的数据,来一个节点1有9999个儿子就挂了。。所以是非完美算法。

  • 0
    @ 2008-10-03 16:08:59

    每个点不会超过100个孩子,开个10000*100的表就可以...

    然后DFS记录每个点的开始和结束时间...

  • 0
    @ 2008-10-03 15:53:18

    前向星存图,要用long long存距离

  • 0
    @ 2008-10-03 14:49:42

    时间戳是个好东西啊,我来解释一下吧。记录dfs第一次访问时间st,记录离开时间en,如果有(st[x]=en[y])那么这样子就是合法的。

    当时做的时候我竟然搞了个10000*10000的数组,bs下自己

    答楼下:没错,如果B的访问时间比A大,那么B的完成时间一定比A大,在同一层嘛,B的完成时间还要加上A的

  • 0
    @ 2008-10-03 14:21:14

    为什么存取非法???

  • 0
    @ 2008-10-03 14:37:00

    感觉解体报告有错

    期望得分:50~60

    ◆方法二:

    对图进行一次dfs,记录每个点第一次被访问到的时间戳begin[i]和完成以这个点为根的树的时间戳finish[i]。则u是v的祖先的充要条件是

    Begin

  • 0
    @ 2008-10-03 19:41:54

    dfs一次把时间戳和距离到根弄出来。 O(n)

    询问,b的时间戳被a包含b就是a的后代,然后把距离作差就是第二问,O(m)

    O(m+n)

    PS:指针+非递归啊....谁说是非完美算法...

  • 0
    @ 2008-10-03 12:43:57

    第一问LCA:

    最近公共祖先(LCA):

    对于有根树T的两个结点u、v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u、v的祖先且x的深度尽可能大。另一种理解方式是把T理解为一个无向无环图,而LCA(T,u,v)即u到v的最短路上深度最小的点。

    要高效解决LCA问题,我们要先介绍RMQ问题:

    RMQ问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j

  • 0
    @ 2008-10-03 17:41:26

    经测试每个点不超过15个儿子,开10000*15的邻接表可以AC,编程难度下降

    DFS记时间戳····

  • 0
    @ 2008-10-03 09:39:15

    搜一遍+并查集,一次性秒杀

  • 0
    @ 2008-10-03 09:23:51

    呃……这道题居然对了,我的方法很锉……

    询问u到v可不可以,就是说LCA(u , v)等不等于u。

    然后用LCA的tarjan算法,统计一下哪两个点之间可以走。

    第二问顺着过一下就行了。

  • 0
    @ 2008-10-02 14:40:42

    又是车

  • 0
    @ 2008-10-01 16:57:51

  • 0
    @ 2008-10-01 13:22:39

    为什么还是你...

信息

ID
1460
难度
7
分类
树结构 | 最近公共祖先 点击显示
标签
递交数
1784
已通过
348
通过率
20%
被复制
9
上传者