Editorial for Floyd hoặc Dijkstra (Cơ bản)
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
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
uses math; const fi=''; oo=100000000; var m,n,k,num,s,t:longint; a,tr:array[1..100,1..100] of longint; re:array[1..100] of longint; procedure rf; var i,x,y,c:longint; begin read(n,m,k); for x:=1 to n-1 do for y:=x+1 to n do begin a[x,y]:=oo; tr[x,y]:=y; a[y,x]:=oo; tr[y,x]:=x; end; for x:=1 to n do tr[x,x]:=x; for i:=1 to m do begin read(x,y,c); a[x,y]:=min(a[x,y],c); a[y,x]:=min(a[y,x],c); end; end; procedure pr; var i,j,k:longint; begin for k:=1 to n do for i:=1 to n do for j:=1 to n do if a[i,j]>a[i,k]+a[k,j] then begin a[i,j]:=a[i,k]+a[k,j]; tr[i,j]:=tr[i,k]; end; end; procedure wf; var i,j,z:longint; begin for i:=1 to k do begin read(z,s,t); if z=0 then writeln(a[s,t]) else begin num:=1; re[1]:=s; repeat s:=tr[s,t]; inc(num); re[num]:=s; until t=s; write(num); for j:=1 to num do write(' ',re[j]); writeln; end; end; end; begin assign(input,fi); reset(input); rf; pr; wf; close(input); end.
Code mẫu của happyboy99x
#include <cstdio> #include <queue> #include <stack> #include <vector> using namespace std; typedef pair<int, int> ii; typedef vector<ii> vii; typedef vector<vii> vvii; #define TR(v, it) for(typeof((v).begin()) it = (v).begin(), _e = (v).end(); it != _e; ++it ) #define INF 1000000000 vvii g; int t[105][105], d[105][105]; int n, m, k; void dijkstra( vvii & g, int s, int d[], int t[] ) { priority_queue<ii> q; q.push(ii(0, s)); for( int i = 0; i < n; ++i ) d[i] = INF; d[s] = 0; t[s] = s; while( !q.empty() ) { int du = q.top().first, u = q.top().second; q.pop(); if (du > d[u]) continue; TR(g[u], it) { int v = it->first, l = it->second; if (d[v] > du + l) { d[v] = du + l; t[v] = u; q.push(ii(d[v], v)); } } } } int main() { scanf( "%d%d%d", &n, &m, &k ); g = vvii(n, vii()); while(m--) { int u, v, l; scanf( "%d%d%d", &u, &v, &l ); g[--u].push_back(ii(--v, l)); g[v].push_back(ii(u, l)); } for( int i = 0; i < n; ++i ) dijkstra(g, i, d[i], t[i]); while(k--) { int q, u, v; scanf( "%d%d%d", &q, &u, &v ); --u; --v; if(q) { stack<int> st; int x = v; st.push(x); do { x = t[u][x]; st.push(x); } while( x != u ); printf( "%d", st.size() ); while(!st.empty()) { printf( " %d", st.top()+1 ); st.pop(); } printf("\n"); } else printf("%d\n", d[u][v]); } return 0; }
Code mẫu của ladpro98
#include <cstring> #include <vector> #include <list> #include <map> #include <set> #include <queue> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <climits> #include <cstdlib> #include <ctime> #include <memory.h> #include <cassert> #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 FORD(i, a, b) for(int i = (a); i > (b); i--) #define REPD(i, a, b) for(int i = (a); i >=(b); i--) #define TR(it, a) for(typeof((a).begin()) it = (a).begin(); it != (a).end(); ++it) #define SZ(a) (int((a).size())) #define ALL(a) (a).begin(), (a).end() #define PB push_back #define MP make_pair #define LL long long #define LD long double #define II pair<int, int> #define X first #define Y second #define VI vector<int> const int N = 101; const int oo = 1000000009; using namespace std; int a[N][N], T[N][N]; int n, m, Q; int main() { ios :: sync_with_stdio(0); cin.tie(0); cin >> n >> m >> Q; REP(i, 1, n) REP(j, 1, n) if (i != j) a[i][j] = oo; REP(i, 1, n) T[i][i] = i; int u, v, c, kind; FOR(i, 0, m) { cin >> u >> v >> c; a[u][v] = a[v][u] = c; T[u][v] = v; T[v][u] = u; } REP(k, 1, n) REP(i, 1, n) REP(j, 1, n) if (a[i][j] > a[i][k] + a[k][j]) { a[i][j] = a[i][k] + a[k][j]; T[i][j] = T[i][k]; } while (Q--) { cin >> kind >> u >> v; if (kind == 0) cout << (a[u][v] >= oo ? -1 : a[u][v]) << '\n'; else { if (u == v) { cout << "2 " << u << ' ' << v << '\n'; continue; } VI path; while (u != v) { path.PB(u); u = T[u][v]; } cout << SZ(path) + 1 << ' '; TR(it, path) cout << *it << ' '; cout << v; cout << '\n'; } } return 0; }
Code mẫu của RR
{$R+,Q+} uses math; const FINP = ''; FOUT = ''; MAXN = 111; var f1,f2 : text; n,m,k : longint; c,trace : array[1..MAXN,1..MAXN] of longint; procedure openF; begin assign(f1,FINP); reset(f1); assign(f2,FOUT); rewrite(f2); end; procedure closeF; begin close(f1); close(f2); end; procedure inp; var i,u,v:longint; begin read(f1,n,m,k); for u:=1 to n do for v:=1 to n do c[u,v]:=1000111000; for i:=1 to m do begin read(f1,u,v,c[u,v]); c[v,u]:=c[u,v]; end; for i:=1 to n do c[i,i]:=0; end; procedure init; var i,j,k:longint; begin for i:=1 to n do for j:=1 to n do trace[i,j]:=j; for k:=1 to n do for i:=1 to n do for j:=1 to n do if c[i,j]>c[i,k]+c[k,j] then begin c[i,j]:=c[i,k]+c[k,j]; trace[i,j]:=trace[i,k]; end; end; procedure solve; var i,q,u,v,count:longint; begin for i:=1 to k do begin read(f1,q,u,v); if q=0 then writeln(f2,c[u,v]) else begin count:=1; q:=u; repeat inc(count); u:=trace[u,v]; until u=v; write(f2,count,' ',q); u:=q; repeat u:=trace[u,v]; write(f2,' ',u); until u=v; writeln(f2); end; end; end; begin openF; inp; init; solve; closeF; end.
Code mẫu của hieult
#include <stdio.h> //#include <conio.h> #define max 1000 #define maxEC 1000 #define maxC max*maxEC long c[max][max],Trace[max][max],n,a,b,T,x; //FILE *p; void Enter() { //p=fopen("D:\\Hoc tap\\test\\FLOYD\\FLOYD.IN0","r"); long m,u,v; scanf("%ld %ld %ld",&n,&m,&T); for(long u=1;u<=n;u++) for(long v=1;v<=n;v++) { if(u==v) c[u][v]=0; else c[u][v]=maxC; } for(long i=1;i<=m;i++) { scanf("%ld %ld",&u,&v); scanf("%ld",&c[u][v]); c[v][u]=c[u][v]; } } void Floyd() { for(long u=1;u<=n;u++) for(long v=1;v<=n;v++) Trace[u][v]=v; for(long k=1;k<=n;k++) for(long u=1;u<=n;u++) for(long v=1;v<=n;v++) if(c[u][v]>c[u][k]+c[k][v]) { c[u][v]=c[u][k]+c[k][v]; Trace[u][v]=Trace[u][k]; } } void Result() { for(long i=1;i<=T;i++) { scanf("%ld %ld %ld",&x,&a,&b); if(c[a][b]==maxC) printf("-1\n"); else { if(x==0) printf("%ld\n",c[a][b]); else { long t=1; long d=a; do { d=Trace[d][b]; t++; }while(d!=b); printf("%ld ",t); do { printf("%ld ",a); a=Trace[a][b]; }while(a!=b); printf("%ld\n",b); } } } } main() { Enter(); Floyd(); Result(); //getch(); }
Code mẫu của ll931110
Program FLOYD; Const input = ''; output = ''; Var F,Trace: array[1..100,1..100] of longint; n,m,k: longint; val: array[1..100] of longint; fi,fo: text; Procedure LoadGraph; Var i,j,u,v: longint; Begin Assign(fi, input); Reset(fi); Readln(fi, n, m, k); For i:= 1 to n do For j:= 1 to n do if i = j then F[i,j]:= 0 else F[i,j]:= 10000000; For i:= 1 to m do Begin Readln(fi, u,v,F[u,v]); F[v,u]:= F[u,v]; End; End; Procedure Floyd; Var k,u,v: longint; Begin For u:= 1 to n do For v:= 1 to n do Trace[u,v]:= v; For k:= 1 to n do For u:= 1 to n do For v:= 1 to n do if F[u,v] > F[u,k] + F[k,v] then Begin F[u,v]:= F[u,k] + F[k,v]; Trace[u,v]:= Trace[u,k]; End; End; Procedure PrintResult; Var x,u,v,i,j,num: longint; Begin Assign(fo, output); Rewrite(fo); For i:= 1 to k do Begin Readln(fi, x, u, v); If x = 0 then writeln(fo, F[u,v]); If x = 1 then Begin num:= 0; Repeat inc(num); val[num]:= u; u:= Trace[u, v]; Until u = v; inc(num); Write(fo, num, ' '); For j:= 1 to num - 1 do write(fo, val[j], ' '); Writeln(fo, v); End; End; Close(fo); Close(fi); End; Begin LoadGraph; Floyd; PrintResult; End.
Code mẫu của skyvn97
const INP = '' ; OUT = '' ; maxn = 100 ; maxc = 10000000 ; var n , m , cau_hoi : integer ; a : array[1..maxn,1..maxn] of longint ; trace : array[1..maxn,1..maxn] of byte ; fi , fo : text ; procedure answer ; var i , j , u , v , pt , loai : integer ; l : array[1..maxn] of integer ; procedure truy_vet( u , v : integer ) ; var k : integer ; begin k := trace[u,v] ; if k = 0 then begin inc( pt ) ; l[pt] := v ; exit ; end ; truy_vet( u , k ) ; truy_vet( k , v ) ; end ; begin for i := 1 to cau_hoi do begin read( fi , loai , u , v ) ; if loai = 0 then writeln( fo , a[u,v] ) { cau hoi loai 0 } else { cau hoi loai 1 } if a[u,v] < 0 then writeln( fo , -1 ) else begin pt := 1 ; l[1] := u ; truy_vet( u , v ) ; write( fo , pt ) ; for j := 1 to pt do write( fo , ' ', l[j] ) ; writeln( fo ) ; end ; end ; end ; procedure process ; var k , u, v : longint ; begin for k := 1 to n do { Floyd } for u := 1 to n do for v := u + 1 to n do if a[u,v] > a[u,k] + a[k,v] then begin a[u,v] := a[u,k] + a[k,v] ; a[v,u] := a[u,v] ; trace[u,v] := k ; trace[v,u] := k ; end ; for u := 1 to n do for v := 1 to n do if a[u,v] = maxc then a[u,v] := -1 ; { Khong ton tai duong di } end ; procedure nhapdl ; var i , j, u , v , val : longint ; begin read( fi , n , m , cau_hoi ) ; for i := 1 to n do for j := 1 to n do a[i,j] := maxc ; for i := 1 to m do begin read( fi , u , v , val ) ; a[u,v] := val ; a[v,u] := val ; end ; for i := 1 to n do a[i,i] := 0 ; end ; procedure mofile ; begin assign( fi , INP ) ; reset( fi ) ; assign( fo , OUT ) ; rewrite( fo ) ; end ; procedure dongfile ; begin close( fi ) ; close( fo ) ; end ; BEGIN mofile ; nhapdl ; process ; answer ; dongfile ; END.
Code mẫu của khuc_tuan
#include <iostream> #include <stdio.h> #include <algorithm> #include <math.h> #include <cstdlib> #include <ctime> #include <string.h> const int maxN = 100010; const int oo = 1000000000; using namespace std; int n, m, kk, nheap; int head[maxN], ke[maxN], next[maxN], ts[maxN], kq[maxN], h[maxN], pos[maxN], d[maxN], truoc[maxN]; void Doc(){ int x, y, z; scanf("%d%d%d", &n, &m, &kk); for(int i = 1; i <= m; i++){ scanf("%d%d%d", &x, &y, &z); ke[i] = y; next[i] = head[x]; head[x] = i; ts[i] = z; ke[i + m] = x; next[i + m] = head[y]; head[y] = i + m; ts[i + m] = z; } } void Doicho(int &x, int &y){ int tg = x; x = y; y = tg; } void Upheap(int i){ if ((i == 1) || (d[h[i / 2]] < d[h[i]])) return; Doicho(h[i], h[i / 2]); Doicho(pos[h[i]], pos[h[i / 2]]); Upheap(i / 2); } void Downheap(int i){ int j = 2 * i; if (j > nheap) return; if (j < nheap && d[h[j]] > d[h[j + 1]]) j++; if (d[h[i]] > d[h[j]]){ Doicho(h[i], h[j]); Doicho(pos[h[i]], pos[h[j]]); Downheap(j); } } void Pus(int x){ nheap++; h[nheap] = x; pos[x] = nheap; Upheap(nheap); } int Pop(){ int tg = h[1]; h[1] = h[nheap]; pos[h[1]] = 1; nheap--; Downheap(1); return tg; } void Dijkstra(int u){ int j, v; nheap = 0; for(int i = 1; i <= n; i++){ pos[i] = 0; truoc[i] = 0; } for(int i = 1; i <= n; i++) d[i] = oo; d[u] = 0; Pus(u); do{ if (nheap == 0) break; u = Pop(); // cout << u << " " << d[u] << endl; j = head[u]; while (j != 0){ v = ke[j]; if (d[v] > d[u] + ts[j]){ d[v] = d[u] + ts[j]; truoc[v] = u; if (pos[v] == 0) Pus(v); else Upheap(pos[v]); } j = next[j]; } } while (true); } void Lam(){ int x, u, v, len; for(int i = 1; i <= kk; i++){ scanf("%d%d%d", &x, &u, &v); //cin >> x >> u >> v; Dijkstra(u); if (x == 0) printf("%d\n", d[v]); else{ len = 0; while (v != u){ len++; kq[len] = v; v = truoc[v]; } len++; kq[len] = u; cout << len << " "; for(int i = len; i >= 1; i--) cout << kq[i] << " "; printf("\n"); } } } void Inkq(){ } int main() { //freopen("Floyd.inp", "r", stdin); //freopen("Floyd.out", "w", stdout); Doc(); Lam(); Inkq(); return 0; }
Comments