zoukankan      html  css  js  c++  java
  • 家谱 并差集

    题意/Description

          现代的人对于本家族血统越来越感兴趣, 现在给出充足的父子关系, 请你编写程序找到 某个人的最早的祖先。


    读入/Input

           输入文件由多行组成, 首先是一系列有关父子关系的描述, 其中每一组父子关系由二行 组成,用#name 的形式描写一组父子关系中的父亲的名字,用+name 的形式描写一组父子关 系中的儿子的名字;接下来用?name 的形式表示要求该人的最早的祖先;最后用单独的一个 $表示文件结束。规定每个人的名字都有且只有 6 个字符,而且首字母大写,且没有任意两 个人的名字相同。最多可能有 1000 组父子关系,总人数最多可能达到 50000 人,家谱中的 记载不超过 30 代。 


    输出/Output

           按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个 空格+祖先的名字+回车。


    题解/solution

           题目很简单,第一眼看就是并差集,小case啦。后来才发现不是就是Time Limit Exceed就是Wrong Answer大哭所以我们开个哈希表来储存名字(最好把字符转化为数字),可以加快速度。然后才发现哈希表不能太大,当然不能太小。就对了。大笑


    代码/Code

     

    var
      h2:array [0..150000] of longint;
      h1:array [0..150000] of string;
      f:array [0..60001] of string;
      a:array [0..60001] of longint;
      t1,t2,k:longint;
      s:string;
      c:char;
    function hash(s:string):longint;
    var
      i:longint;
    begin
      hash:=0;
      for i:=1 to length(s) do
        hash:=hash*4+ord(s[i]);
    end;
    
    function fd(s:string):longint;
    var
      x:longint;
    begin
      x:=hash(s);
      while h1[x]<>'' do
        begin
          if h1[x]=s then exit(h2[x]);
          inc(x);
          if x>150000 then x:=0;
        end;
      exit(0);
    end;
    
    procedure ins(s:string;a:longint);
    var
      i,x:longint;
    begin
      x:=hash(s);
      while h1[x]<>'' do
        begin
          inc(x);
          if x>150000 then x:=0;
        end;
      h1[x]:=s; h2[x]:=a;
    end;
    
    function find(x:longint):longint;
    var
      y,t,k:longint;
    begin
      y:=x;
      while a[y]>0 do
        y:=a[y];
      k:=y;
      y:=x;
      while a[y]>0 do
        begin
          t:=a[y];
          a[y]:=k;
          y:=t;
        end;
      find:=k;
    end;
    
    procedure union(x,y:longint);
    var
      u,v:longint;
    begin
      u:=find(x);
      v:=find(y);
      a[v]:=u;
    end;
    
    procedure init;
    var
      i:longint;
    begin
      for i:=1 to 150000 do
        begin
          h1[i]:=''; h2[i]:=0;
        end;
      while 1=1 do
        begin
          readln(s);
          if s='$' then halt;
          c:=s[1]; delete(s,1,1);
          t1:=fd(s);
          if t1=0 then
            begin
              inc(k); f[k]:=s; t1:=k; ins(s,k);
            end;
          if c='#' then
            t2:=t1;
          if c='+' then
            union(t2,t1);
          if c='?' then
            begin
              writeln(s,' ',f[find(t1)]);
            end;
        end;
    end;
    
    begin
      init;
    end.
    



  • 相关阅读:
    POJ 1328 Radar Installation
    POJ 1700 Crossing River
    POJ 1700 Crossing River
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3253 Fence Repair (贪心,优先队列)
    poj 3069 Saruman's Army(贪心)
    poj 3069 Saruman's Army(贪心)
    Redis 笔记与总结2 String 类型和 Hash 类型
    数据分析方法有哪些_数据分析方法
    数据分析方法有哪些_数据分析方法
  • 原文地址:https://www.cnblogs.com/zyx-crying/p/9319698.html
Copyright © 2011-2022 走看看