[GRYZ2015]Graph

题目描述

给出 N 个点,M 条边的有向图,对于每个点 v,求 A(v) 表示从点 v 出发,能到达的编号最大的点。

输入格式

第 1 行,2 个整数 N,M。 接下来 M 行,每行 2 个整数 Ui,Vi,表示边 ⟨Ui,Vi⟩。点用 1,2,...,N 编号。

输出格式

N 个整数 A(1),A(2),...,A(N)。

样例输入

4 3

1 2

2 4

4 3

样例输出

4 4 3 4

数据范围

对于 60% 的数据,1 ≤ N,K ≤ 10^3

对于 100% 的数据,1 ≤ N,M ≤ 10^5。

思路

  图的遍历。DFS。

  用邻接矩阵不开动态数组60分。

var f:array[1..2000000,1..2000000] of boolean;
    ff:packed array[1..10000] of boolean;
    a:array[1..10000] of longint;
    n,m,i,sum,y,z:longint;

function max(a,b:longint):longint;
begin
    if a>b then exit(a) else exit(b);
end;

procedure dfs(x:longint);
var i:longint;
begin
    ff[x]:=true;
    sum:=max(sum,x);
    for i:=1 to n do
        if (f[x,i])and(not ff[i]) then
            dfs(i);
end;

procedure intt;
begin
    assign(input,'graph.in');
    assign(output,'graph.out');
    reset(input);
    rewrite(output);
end;

procedure outt;
begin
    close(input);
    close(output);
end;

begin
    //intt;
    writeln(sizeof(f) div 1024 div 1024);
    fillchar(f,sizeof(f),false);
    readln(n,m);
    for i:=1 to m do
        begin
            readln(y,z);
            f[y,z]:=true;
        end;
    for i:=1 to n do
        begin
            fillchar
            (ff,sizeof(ff),false);
            sum:=0;
            dfs(i);
            a[i]:=sum;
        end;
    for i:=1 to n do write(a[i],' ');
    //outt;
end.
View Code

  如果可以用动态数组的话或许可以多卡几个点。

  用边表存储可以A掉。

program df;
var head,f:array[1..100000]of longint;
    next,v:array[1..100000]of longint;
    b:array[1..100000]of boolean;
    n,i,m,j,a1,a2,max:longint;
procedure dfs(a1:longint);
  var b1:longint;
  begin
    if b[a1]
      then exit;
    b[a1]:=true;
    f[a1]:=max;
    b1:=head[a1];
    while b1<>0 do
      begin
        dfs(v[b1]);
        b1:=next[b1];
      end;
  end;
begin
  assign(input,'graph.in');
  assign(output,'graph.out');
  reset(input);
  rewrite(output);
  read(n,m);
  for i:=1 to m do
    begin
      read(a1,a2);
      next[i]:=head[a2];
      head[a2]:=i;
      v[i]:=a1;
    end;
  for i:=n downto 1 do
    if not b[i]
      then
        begin
          max:=i;
          dfs(i);
        end;
  for i:=1 to n-1 do
    write(f[i],' ');
  writeln(f[n]);
  close(input);
  close(output);
end.
View Code

强连通分量

拓扑排序

DP/BFS

同样可以求解此题。

原文地址:https://www.cnblogs.com/yangqingli/p/4935861.html