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.
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