【Vijos1790】拓扑编号

来源:互联网 发布:java超市管理系统 编辑:程序博客网 时间:2024/04/30 23:04

H国有n个城市,城市与城市之间有m条单向道路,满足任何城市不能通过某条路径回到自己。

现在国王想给城市重新编号,令第i个城市的新的编号为a[i],满足所有城市的新的编号都互不相同,并且编号为[1,n]之间的整数。国王认为一个编号方案是优美的当且仅当对于任意的两个城市i,j,如果i能够到达j,那么a[i]应当<a[j]。

优美的编号方案有很多种,国王希望使1号城市的编号尽可能小,在此前提下,使得2号城市的编号尽可能小...依此类推。

【题解】

反向建图,拓扑排序时每次选取入度为0的编号最大的节点,最后反向输出,注意题目所求的不是1-n编号对应的城市而是1-n城市对应的编号,编号最大节点使用优先队列维护。

【代码】

program escape;var  t, o: longint;  a: array[-1..200001, 1..2] of longint;  b: array[-1..300000] of longint;  i, j, k, n, m: longint;  c: array[0..300000] of longint;  cd: array[-1..300000] of longint;  d: array[-1..300000] of longint;  e: array[-1..300000] of longint;  procedure qsort(x, y: longint);  var    i, j, m1, m2, t: longint;  begin    i := x;    j := y;    m1 := a[(i + j) div 2, 2];    m2 := a[(i + j) div 2, 1];    repeat      while (a[i, 2] < m1) or ((a[i, 2] = m1) and (a[i, 1] < m2)) do        Inc(i);      while (a[j, 2] > m1) or ((a[j, 2] = m1) and (a[j, 1] > m2)) 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;    if i < y then      qsort(i, y);    if j > x then      qsort(x, j);  end;  procedure hup(m: longint);  var    i: longint;    t: longint;  begin    i := m div 2;    while i <> 0 do    begin      if c[m] < c[i] then        break      else      begin        t:=c[m];c[m]:=c[i];c[i]:=t;m := i;        i := m div 2;      end;    end;  end;  procedure hdown(i: longint);  var    j: longint;    t: longint;  begin    if c[i * 2] < c[i * 2 + 1] then      j := i * 2 + 1    else      j := i * 2;    if (i * 2 + 1 > c[0]) and (j = i*2+1) then      Dec(j);    while (c[i] < c[j]) and (j <= c[0]) do    begint:=c[i];c[i]:=c[j];c[j]:=t;      i := j;      if c[i * 2] < c[i * 2 + 1] then        j := i * 2 + 1      else        j := i * 2;    if (i * 2 + 1 > c[0]) and (j = i*2+1) then      Dec(j);    //堆操作不能忘了这句话- -    end;  end;  procedure insert(x: longint);  begin    Inc(c[0]);    c[c[0]] := x;    hup(c[0]);  end;  function top: longint;  var    t: longint;  begin    top := c[1];    t := c[1];    c[1] := c[c[0]];    c[c[0]] := t;    Dec(c[0]);    hdown(1);  end;begin    readln(n, m);    for i := 1 to m do      readln(a[i, 1], a[i, 2]);    a[m + 1, 2] := 0;    c[0] := 0;    qsort(1, m);    for i := 1 to n do      b[i] := 0;    for i := 1 to n do      cd[i] := 0;    for i := 1 to m do      if b[a[i, 2]] = 0 then        b[a[i, 2]] := i;    for i := 1 to m do      Inc(cd[a[i, 1]]);    for i := 1 to n do      if cd[i] = 0 then        insert(i);    if (c[0] = 0) then      writeln(-1)    else      for i := 1 to n do      begin        k := top;        d[n - i + 1] := k;        e[d[n - i + 1]] := n - i + 1;        j := b[k];        while a[j, 2] = k do        begin          Dec(cd[a[j, 1]]);          if cd[a[j, 1]] = 0 then            insert(a[j, 1]);          Inc(j);        end;        if (i <> n) and (c[0] = 0) then        begin          writeln(-1);          break;        end;          if i = n then        begin          for j := 1 to n - 1 do            Write(e[j], ' ');          writeln(e[n]);        end;      end;end.




0 0
原创粉丝点击