FLOYD spoj – Floyd hoặc Dijkstra ( Cơ bản )
Nguồn đề bài: http://vn.spoj.com/problems/FLOYD/ 1. Đề bài FLOYD Dijkstra căn bản Cho đơn đồ thị vô hướng N đỉnh và M cạnh, trọng số các cạnh đều nguyên dương. Có 2 loại câu hỏi : 0 u v : Cho biết đường đi ngắn nhất từ u tới v có độ dài là bao nhiêu. 1 u v : Hãy chỉ ra 1 đường ...
Nguồn đề bài: http://vn.spoj.com/problems/FLOYD/
1. Đề bài FLOYD Dijkstra căn bản
Cho đơn đồ thị vô hướng N đỉnh và M cạnh, trọng số các cạnh đều nguyên dương. Có 2 loại câu hỏi :
0 u v : Cho biết đường đi ngắn nhất từ u tới v có độ dài là bao nhiêu.
1 u v : Hãy chỉ ra 1 đường đi ngắn nhất từ u => v
Bài cơ bản này nhằm kiểm tra kỹ năng xây dựng các module chương trình con dành cho truy vết 1 cách hợp lý, sử dụng nhuần nhuyễn chương trình con, lời gọi hàm .
Input
Dòng 1 : 3 số nguyên N , M , K . ( 1 ≤ N ≤ 100 , 1 ≤ M ≤ N*(N-1)/2 , 1 ≤ K ≤ 1000 )
M dòng tiếp theo , dòng thứ i gồm 3 số nguyên dương u , v , c cho biết cạnh (u,v) có trọng số là c ( 1 ≤ c ≤ 10000 )
K dòng tiếp theo là K câu hỏi , dòng thứ j sẽ có định dạng như đã nêu ở trên .
Output
Ứng với mỗi câu hỏi trong K câu hỏi thì ta phải trả lời trên mỗi dòng như sau .
Câu hỏi 0 u v : Ghi ra 1 số nguyên duy nhất là độ dài đường đi ngắn nhất từ u -> v.
Câu hỏi 1 u v : Ghi ra số đầu tiên là số X là số đỉnh trên đường đi ngắn nhất này , tiếp đó ghi ra X số là chỉ số các đỉnh theo thứ tự xuất hiện trên hành trình .
Example
Input:
3 3 2
1 2 3
2 3 1
1 3 5
0 1 2
1 1 3
Output:
3
3 1 2 3
2. code tham khảo Dijkstra, Floyd (pascal và c++)
a. Code Dijkstra Pascal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | const fi='; nmax=100; vc=100000;//high(longint); type data=longint; var f:text; n,m,k:data; A:array[0..nmax+1,0..nmax+1] of data; D:array[0..nmax+1] of data; free:array[0..nmax+1] of boolean; trace:array[0..nmax+1] of data; luu:array[0..nmax+1] of data; spt:data; procedure dijkstra(s,t:data); var i,j,u,v,min:data; begin for i:=1 to n do begin free[i]:=true; d[i]:=a[s,i]; trace[i]:=s; end; repeat min:=vc; u:=0; for i:=1 to n do if (free[i]) and (d[i]<min) then begin min:=d[i]; u:=i; end; if (u=0) or (u=t) then break; free[u]:=false; for v:=1 to n do begin if (free[v]) and (d[v]>d[u]+a[u,v]) then begin d[v]:=d[u]+a[u,v]; trace[v]:=u; end; end; until FALSE; end; procedure truyvet(v:data); var x:data; i:data; begin if trace[v]<>0 then begin truyvet(trace[v]); inc(spt); luu[spt]:=v; end else begin inc(spt); luu[spt]:=v; end; end; procedure docfile; var i,j,u,v,c,tl:data; begin assign(f,fi); reset(f); readln(f,n,m,k); for i:=1 to n do for j:=1 to n do if i=j then a[i,j]:=0 else a[i,j]:=vc; for i:=1 to m do begin readln(f,u,v,c); a[u,v]:=c; a[v,u]:=c; end; for i:=1 to k do begin readln(f,tl,u,v); if tl=0 then begin dijkstra(u,v); writeln(d[v]); end else begin dijkstra(u,v); if u<>v then begin spt:=0; trace[u]:=0; truyvet(v); write(spt,' '); for j:=1 to spt do write(luu[j],' '); writeln; end else writeln('2 ',u,' ',v); end; end; close(f); end; begin docfile; readln; end. |
b. Code Dijkstra c++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | #include <bits/stdc++.h> using namespace std; const int maxn=100; const int maxd=10e6; int n,m,k; int a[maxn][maxn]; void Init() { scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=maxd; int u,v,c; for (int i=1;i<=m;i++) { scanf("%d%d%d",
Có thể bạn quan tâm
-1
|