Hướng dẫn giải của ĐUỔI BẮT


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

const fi='';
      fo='';
      maxn=1010;
      maxm=10010;
var n,k,m,last,sm,dem:longint;
    s,f:array[1..10] of longint;
    a:array[1..maxn,1..maxn] of boolean;
    b:array[1..maxm,0..1] of longint;
    free:array[1..maxn] of boolean;
    num,low,d,st,sl,q,dau,dau1:array[1..maxn] of longint;
    re:array[1..10] of boolean;

procedure rf;
var i:longint;
begin
     assign(input,fi); reset(input);
     readln(n,m,k);
     for i:=1 to k do readln(s[i],f[i]);
     for i:=1 to m do
     begin
          readln(b[i,0],b[i,1]);
          a[b[i,0],b[i,1]]:=true;
          a[b[i,1],b[i,0]]:=true;
     end;
     close(input);
end;

function min(x,y:longint):longint;
begin
     if x<y then min:=x else min:=y;
end;

function pop:longint;
begin
     pop:=st[last];
     dec(last);
end;

procedure push(x:longint);
begin
     inc(last);
     st[last]:=x;
end;

procedure visit(x,y:longint);
var i:longint;
begin
     inc(dem); num[x]:=dem; low[x]:=dem;
     push(x);
     for i:=1 to n do
         if free[i] and a[x,i] and (i<>y) then
            if num[i]>0 then low[x]:=min(low[x],num[i])
            else
            begin
                 visit(i,x);
                 low[x]:=min(low[x],low[i]);
            end;
     if num[x]=low[x] then
     begin
          inc(sm);
          repeat
                i:=pop;
                free[i]:=false;
                d[i]:=sm;
                inc(sl[sm]);
          until i=x;
          if d[x]<>sm then
          begin
               d[x]:=sm;
               inc(sl[sm]);
          end;
     end;
end;

procedure pr;
var i,num,j,jj:longint; kt:boolean;
begin
     dem:=0; sm:=0;
     for i:=1 to n do free[i]:=true;
     for i:=1 to n do
         if free[i] then visit(i,0);
     for i:=1 to k do re[i]:=true;
     if sm>=n-1 then exit;
     for i:=1 to k do
     begin
          if sl[d[f[i]]]>=3 then
          begin
               re[i]:=false;
               continue;
          end;
          {soi}
          fillchar(dau1,sizeof(dau1),0);
          q[1]:=s[i]; num:=1; j:=1; dau1[s[i]]:=1;
          repeat
                for jj:=1 to n do
                    if (dau1[jj]=0) and a[jj,q[j]] then
                    begin
                         inc(num);
                         q[num]:=jj;
                         dau1[jj]:=dau1[q[j]]+1;
                    end;
                inc(j);
          until j>num;
          {tho}
          kt:=false;
          fillchar(dau,sizeof(dau),0);
          q[1]:=f[i]; num:=1; j:=1; dau[f[i]]:=1;
          repeat
                for jj:=1 to n do
                    if (dau[jj]=0) and a[q[j],jj] then
                    begin
                         inc(num);
                         q[num]:=jj;
                         dau[jj]:=dau[q[j]]+1;
                         if (sl[d[jj]]>=3) and (dau[jj]<dau1[jj]) then
                         begin
                              kt:=true;
                              break;
                         end;
                    end;
                inc(j);
          until (j>num) or kt;
          if kt then re[i]:=false;
     end;
end;

procedure wf;
var i:longint;
begin
     assign(output,fo); rewrite(output);
     for i:=1 to k do
         if re[i] then writeln(1)
         else writeln(0);
     close(output);
end;

begin
     rf;
     pr;
     wf;
end.

Code mẫu của ladpro98

#include <bits/stdc++.h>
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, a, b) for (int i = (a); i <= (b); ++i)
#define X first
#define Y second
#define VI vector<int>
#define endl '\n'

const int N = 1010;

using namespace std;

typedef pair<int, int> II;

int n, timer, m, nTest;
VI a[N];
int low[N], num[N], dx[N], dy[N];
bool inCycle[N], was[N];
II test[N];

void dfs(int u, int par) {
  num[u] = ++timer; low[u] = N;
  for (int v: a[u])
  if (v != par) {
    if (num[v]) {
      low[u] = min(low[u], num[v]);
    } else {
      dfs(v, u);
      low[u] = min(low[u], low[v]);
    }
  }
  inCycle[u] = low[u] <= num[u];
}

void bfs(int source, int d[]) {
  REP(i, 1, n) was[i] = d[i] = 0;
  queue<int> Q;
  Q.push(source); was[source] = 1;
  while (!Q.empty()) {
    int u = Q.front(); Q.pop();
    for (auto v: a[u])
    if (!was[v]) {
      was[v] = 1;
      d[v] = d[u] + 1;
      Q.push(v);
    }
  }
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  #ifdef _LAD_
    freopen("THTRACE.in", "r", stdin);
  #endif // _LAD_
  cin >> n >> m >> nTest;
  FOR(i, 0, nTest) cin >> test[i].X >> test[i].Y;
  int u, v;
  FOR(i, 0, m) {
    cin >> u >> v;
    a[u].push_back(v);
    a[v].push_back(u);
  }
  REP(i, 1, n)
  if (!num[i]) dfs(i, 0);
  FOR(i, 0, nTest) {
    bfs(test[i].X, dx);
    bfs(test[i].Y, dy);
    bool canEscape = 0;
    REP(i, 1, n)
    if (inCycle[i]) {
      canEscape |= dx[i] > dy[i];
      if (canEscape) break;
    }
    cout << !canEscape << endl;
  }
  return 0;
}

Code mẫu của RR

//Written by Nguyen Thanh Trung
{$R+,Q+}
{$Mode objFPC}
uses math;
const
  FINP          =       '';
  FOUT          =       '';
  MAXN          =       1111;
  oo            =       1000111000;
type
  Tqueue        =       object
        val     :       array[1..MAXN] of longint;
        first   :       longint;
        last    :       longint;
        procedure push(u:longint);
        procedure pop(var u:longint);
        function empty:boolean;
  end;
  list          =       ^node;
  node          =       record
                                u,c:longint;
                                next:list;
                        end;
var
  f1,f2         :       text;
  n,m,k         :       longint;
  ke            :       array[1..MAXN] of list;
  dtho,dsoi     :       array[1..MAXN] of longint;
  soi,tho       :       array[1..11] of longint;
  low,num       :       array[1..MAXN] of longint;
  father        :       array[1..MAXN] of longint;
  queue         :       Tqueue;

procedure openF;
    begin
      assign(f1,FINP); reset(f1);
      assign(f2,FOUT); rewrite(f2);
    end;
procedure closeF;
    begin
      close(f1);
      close(f2);
    end;
procedure add(u:longint; var a:list); inline;
    var
      p:list;
    begin
      new(p); p^.u:=u;
      p^.next:=a; a:=p;
    end;
procedure inp;
    var
      u,v,c:longint;
    begin
      read(f1,n,m,k);
      for k:=1 to k do
        read(f1,soi[k],tho[k]);
      for m:=1 to m do
        begin
          read(f1,u,v);
          add(v,ke[u]);
          add(u,ke[v]);
        end;
    end;
procedure DFS(u:longint); inline;
    var
      p:list;
      v:longint;
    begin
      inc(m); num[u]:=m; low[u]:=MAXN;
      p:=ke[u];
      while p<>nil do
        begin
          v:=p^.u; p:=p^.next;
          if v=father[u] then continue;
          if num[v]=0 then
            begin
              father[v]:=u; DFS(v);
              low[u]:=min(low[u],low[v]);
            end
          else low[u]:=min(low[u],num[v]);
        end;
    end;
function Tqueue.empty:boolean; inline;
    begin
      exit(first>last);
    end;
procedure Tqueue.push(u:longint); inline;
    begin
      inc(last);
      val[last]:=u;
    end;
procedure Tqueue.pop(var u:longint); inline;
    begin
      u:=val[first];
      inc(first);
    end;
procedure BFS(typ,start:longint); inline;
    var
      u,v:longint;
      p:list;
    begin
      if typ=1 then dsoi[start]:=0
      else dtho[start]:=0;
      queue.first:=1; queue.last:=0; queue.push(start);
      while not queue.empty do
        begin
          queue.pop(u);
          p:=ke[u];
          while p<>nil do
            begin
              v:=p^.u; p:=p^.next;
              if ((typ=1) and (dsoi[v]>dsoi[u]+1))
              or ((typ=2) and (dtho[v]>dtho[u]+1)) then
                begin
                  if typ=1 then dsoi[v]:=dsoi[u]+1
                  else dtho[v]:=dtho[u]+1;
                  queue.push(v);
                end;
            end;
        end;
    end;
procedure solve;
    var
      i:longint;
      check:boolean;
    begin
      m:=0;
      DFS(1);
      for k:=1 to k do
        begin
          for i:=1 to n do dsoi[i]:=oo;
          for i:=1 to n do dtho[i]:=oo;
          BFS(1,soi[k]);
          BFS(2,tho[k]);
          check:=false;
          for i:=1 to n do
          if low[i]<=num[i] then
            if dtho[i]<dsoi[i] then
              begin
                check:=true;
                break;
              end;
          if check then writeln(f2,0)
          else writeln(f2,1);
        end;
    end;

begin
  openF;
  inp;
  solve;
  closeF;
end.

Code mẫu của khuc_tuan

// {$APPTYPE CONSOLE}
 {$mode delphi}

uses math, sysutils;

type
    Edge = class
        u, v : integer;
        isUsed, isBridge : boolean;

        constructor init(u, v : integer);
    end;

constructor Edge.init(u, v : integer);
begin
    self.u := u;
    self.v := v;
end;

type
    List = class
        e : Edge;
        n : List;
    end;

procedure AddList(var l : List; e : Edge);
var
    p : List;
begin
    p := List.Create;
    p.e := e;
    p.n := l;
    l := p;
end;

type
    ArrInt = array[1..1000] of integer;

var
    ke : array[1..1000] of List;
    i, u, v, n, m, k : integer;
    soi, tho : array[1..10] of integer;
    cure : Edge;
    incircle, vs : array[1..1000] of boolean;
    num, low : array[1..1000] of integer;
    ds, dt : ArrInt;
    Q : array[1..5000] of integer;
    le, ri : integer;
    counter : integer;

    edges : array[1..100000] of Edge;
    ne : integer;

procedure add(i : integer);
begin
    inc(ri);
    if ri > 5000 then ri := 1;
    Q[ri] := i;
end;

function del : integer;
begin
    del := Q[le];
    if le = ri then
    begin
        le := 1;
        ri := 0;
    end
    else
    begin
        inc(le);
        if le > 5000 then le := 1;
    end;
end;

procedure shortestPath( s : integer; var d : ArrInt);
var
    u, v, i : integer;
    p : List;
begin
    for i:=1 to n do d[i] := 1000000000;
    d[s] := 0;
    le := 1;
    ri := 0;
    add(s);
    while ri <> 0 do
    begin
        u := del;
        p := ke[u];
        while p<>nil do
        begin
            v := p.e.u + p.e.v - u;
            if d[v] > d[u] + 1 then
            begin
                d[v] := d[u] + 1;
                add(v);
            end;
            p := p.n;
        end;
    end;
end;

procedure dfs(i : integer);
var
    p : List;
    e : Edge;
    j : integer;
begin
    vs[i] := true;
    inc(counter);
    num[i] := counter;
    low[i] := counter;
    p := ke[i];
    while p<>nil do
    begin
        e := p.e;
        if not e.isUsed then                                             
        begin
            j := e.u + e.v - i;
            if not vs[j] then
            begin
                e.isUsed := true;
                dfs(j);
                if low[j] > num[i] then
                begin
                    e.isBridge := true;
                end
                else
                begin
                    incircle[e.u] := true;
                    incircle[e.v] := true;
                end;
                low[i] := min(low[i], low[j]);
            end
            else
                low[i] := min(low[i], num[j]);
        end;
        p := p.n;
    end;
end;

procedure process(s, t : integer);
var
    i : integer;
begin
    for i:=1 to ne do
    begin
        edges[i].isUsed := false;
        edges[i].isBridge := false;
    end;
    fillchar( vs, sizeof(vs), false);
    fillchar( incircle, sizeof(incircle), false);
    counter := 0;
    dfs(s);
    if not vs[t] then
    begin
        writeln(0);
        exit;
    end;
    shortestPath( s, ds);
    shortestPath( t, dt);
    for i:=1 to n do
        if incircle[i] and (ds[i] > dt[i]) then
        begin
            writeln(0);
            exit;
        end;
    writeln(1);
end;

begin
    read(n,m,k);
    for i:=1 to k do
    begin
        read(soi[i], tho[i]);
    end;
    ne := 0;
    for i:=1 to m do
    begin
        read(u,v);
        cure := Edge.init(u,v);
        inc(ne);
        edges[ne] := cure;
        AddList( ke[u], cure);
        AddList( ke[v], cure);
    end;
    for i:=1 to k do
    begin
        process(soi[i], tho[i]);
    end;
end.

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.