ผลต่างระหว่างรุ่นของ "Algo lab/dijkstra"
ไปยังการนำทาง
ไปยังการค้นหา
Jittat (คุย | มีส่วนร่วม) |
Jittat (คุย | มีส่วนร่วม) |
||
| (ไม่แสดง 1 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน) | |||
| แถว 55: | แถว 55: | ||
for(int x=0; x<n; x++) { | for(int x=0; x<n; x++) { | ||
if((!is_visited[x]) && (D[x] < du)) { | if((!is_visited[x]) && (D[x] < du)) { | ||
| − | + | u = x; | |
| − | + | du = D[x]; | |
} | } | ||
} | } | ||
| แถว 68: | แถว 68: | ||
//cout << D[u] << " " << w << " " << D[v] << endl; | //cout << D[u] << " " << w << " " << D[v] << endl; | ||
if(D[u] + w < D[v]) { | if(D[u] + w < D[v]) { | ||
| − | + | D[v] = D[u] + w; | |
} | } | ||
} | } | ||
| แถว 83: | แถว 83: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | == Fast version (newer) (2026-02-16) == | ||
| + | <syntaxhighlight lang="cpp"> | ||
| + | #include <iostream> | ||
| + | #include <vector> | ||
| + | #include <set> | ||
| + | using namespace std; | ||
| + | const int MAX_N = 100010; | ||
| + | |||
| + | int n,m; | ||
| + | vector<int> adj[MAX_N]; | ||
| + | vector<int> lengths[MAX_N]; | ||
| + | int deg[MAX_N]; | ||
| + | int parents[MAX_N]; | ||
| + | void read_input() | ||
| + | { | ||
| + | cin >> n >> m; | ||
| + | for(int u=0; u<n; u++) { | ||
| + | deg[u] = 0; | ||
| + | } | ||
| + | |||
| + | for(int i=0; i<m; i++) { | ||
| + | int u,v,l; | ||
| + | cin >> u >> v >> l; u--; v--; | ||
| + | |||
| + | adj[u].push_back(v); | ||
| + | adj[v].push_back(u); | ||
| + | deg[u]++; deg[v]++; | ||
| + | lengths[u].push_back(l); | ||
| + | lengths[v].push_back(l); | ||
| + | } | ||
| + | } | ||
| + | const int INFINITY = 1000000000; | ||
| + | bool visited[MAX_N]; | ||
| + | int D[MAX_N]; | ||
| + | set<pair<int,int>> Q; | ||
| + | |||
| + | void dijkstra(int s) | ||
| + | { | ||
| + | for(int u=0; u<n; u++) { | ||
| + | visited[u] = false; | ||
| + | D[u] = INFINITY; | ||
| + | parents[u] = -1; | ||
| + | } | ||
| + | D[s] = 0; | ||
| + | Q.insert({ D[s], s }); | ||
| + | |||
| + | for(int i=0; i<n; i++) { | ||
| + | // find u that minimizes D[u] & visited[u] == false | ||
| + | if(Q.empty()) | ||
| + | return; | ||
| + | auto lu = *(Q.begin()); | ||
| + | Q.erase(Q.begin()); | ||
| + | int u = lu.second; | ||
| + | |||
| + | visited[u] = true; | ||
| + | for(int d = 0; d < deg[u]; d++) { | ||
| + | int v = adj[u][d]; | ||
| + | int l = lengths[u][d]; | ||
| + | if(D[v] > D[u] + l) { | ||
| + | Q.erase({ D[v], v }); | ||
| + | D[v] = D[u] + l; | ||
| + | parents[v] = u; | ||
| + | Q.insert({ D[v], v }); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | |||
| + | int main() | ||
| + | { | ||
| + | read_input(); | ||
| + | dijkstra(0); | ||
| + | cout << D[n-1] << endl; | ||
| + | } | ||
| + | </syntaxhighlight> | ||
| + | |||
== Fast version (new) == | == Fast version (new) == | ||
| แถว 141: | แถว 218: | ||
int v = adj[u][dd]; | int v = adj[u][dd]; | ||
if(d[v] > d[u] + weights[u][dd]) { | if(d[v] > d[u] + weights[u][dd]) { | ||
| − | + | d[v] = d[u] + weights[u][dd]; | |
| − | + | Q.insert(make_pair(d[v],v)); | |
} | } | ||
} | } | ||
| แถว 214: | แถว 291: | ||
do { | do { | ||
if(Q.empty()) | if(Q.empty()) | ||
| − | + | return; | |
pair<int,int> uu = *(Q.begin()); | pair<int,int> uu = *(Q.begin()); | ||
Q.erase(Q.begin()); | Q.erase(Q.begin()); | ||
| แถว 226: | แถว 303: | ||
//cout << D[u] << " " << w << " " << D[v] << endl; | //cout << D[u] << " " << w << " " << D[v] << endl; | ||
if(D[u] + w < D[v]) { | if(D[u] + w < D[v]) { | ||
| − | + | D[v] = D[u] + w; | |
| − | + | Q.insert(make_pair(D[v],v)); | |
} | } | ||
} | } | ||
รุ่นแก้ไขปัจจุบันเมื่อ 06:42, 16 กุมภาพันธ์ 2569
เนื้อหา
Slower version
#include <iostream>
#include <vector>
using namespace std;
const int MAX_N = 1000010;
vector<int> adj[MAX_N];
vector<int> weights[MAX_N];
int n,m;
int deg[MAX_N];
void read_input()
{
cin >> n >> m;
for(int i=0; i<n; i++) {
deg[i] = 0;
}
for(int i=0; i<m; i++) {
int a,b,w;
cin >> a >> b >> w;
a--; b--;
adj[a].push_back(b);
weights[a].push_back(w);
deg[a]++;
adj[b].push_back(a);
weights[b].push_back(w);
deg[b]++;
}
}
bool is_visited[MAX_N];
int D[MAX_N];
const int INFINITY = 1000000000;
void dijkstra(int s)
{
for(int i=0; i<n; i++) {
is_visited[i] = false;
D[i] = INFINITY;
}
D[s] = 0;
for(int i=0; i<n; i++) {
// find u with minimum D[u] such that is_visited[u] = false
int u = -1;
int du = INFINITY;
for(int x=0; x<n; x++) {
if((!is_visited[x]) && (D[x] < du)) {
u = x;
du = D[x];
}
}
//cout << u << " - " << du << endl;
for(int j=0; j<deg[u]; j++) {
int v = adj[u][j]; // edge (u,v)
int w = weights[u][j];
//cout << D[u] << " " << w << " " << D[v] << endl;
if(D[u] + w < D[v]) {
D[v] = D[u] + w;
}
}
is_visited[u] = true;
}
}
int main()
{
read_input();
dijkstra(0);
cout << D[n-1] << endl;
}
Fast version (newer) (2026-02-16)
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int MAX_N = 100010;
int n,m;
vector<int> adj[MAX_N];
vector<int> lengths[MAX_N];
int deg[MAX_N];
int parents[MAX_N];
void read_input()
{
cin >> n >> m;
for(int u=0; u<n; u++) {
deg[u] = 0;
}
for(int i=0; i<m; i++) {
int u,v,l;
cin >> u >> v >> l; u--; v--;
adj[u].push_back(v);
adj[v].push_back(u);
deg[u]++; deg[v]++;
lengths[u].push_back(l);
lengths[v].push_back(l);
}
}
const int INFINITY = 1000000000;
bool visited[MAX_N];
int D[MAX_N];
set<pair<int,int>> Q;
void dijkstra(int s)
{
for(int u=0; u<n; u++) {
visited[u] = false;
D[u] = INFINITY;
parents[u] = -1;
}
D[s] = 0;
Q.insert({ D[s], s });
for(int i=0; i<n; i++) {
// find u that minimizes D[u] & visited[u] == false
if(Q.empty())
return;
auto lu = *(Q.begin());
Q.erase(Q.begin());
int u = lu.second;
visited[u] = true;
for(int d = 0; d < deg[u]; d++) {
int v = adj[u][d];
int l = lengths[u][d];
if(D[v] > D[u] + l) {
Q.erase({ D[v], v });
D[v] = D[u] + l;
parents[v] = u;
Q.insert({ D[v], v });
}
}
}
}
int main()
{
read_input();
dijkstra(0);
cout << D[n-1] << endl;
}
Fast version (new)
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int MAX_N = 100010;
int n,m;
vector<int> adj[MAX_N];
vector<int> weights[MAX_N];
int deg[MAX_N];
set<pair<int,int>> Q;
void read_input()
{
cin >> n >> m;
for(int u=0; u<n; u++) deg[u] = 0;
for(int i=0; i<m; i++) {
int a,b,w;
cin >> a >> b >> w; a--; b--;
adj[a].push_back(b);
adj[b].push_back(a);
weights[a].push_back(w);
weights[b].push_back(w);
deg[a]++;
deg[b]++;
}
}
int d[MAX_N];
const int INFINITY = 1000000000;
bool explored[MAX_N];
void dijkstra(int s)
{
for(int u=0; u<n; u++) {
d[u] = INFINITY;
explored[u] = false;
}
d[0] = 0;
Q.insert(make_pair(0,s));
while(!Q.empty()) {
auto pu = *(Q.begin());
Q.erase(Q.begin());
int u = pu.second;
if(explored[u])
continue;
//cout << u << " " << du << endl;
explored[u] = true;
for(int dd=0; dd<deg[u]; dd++) {
int v = adj[u][dd];
if(d[v] > d[u] + weights[u][dd]) {
d[v] = d[u] + weights[u][dd];
Q.insert(make_pair(d[v],v));
}
}
}
}
main()
{
read_input();
dijkstra(0);
cout << d[n-1] << endl;
}
Fast version (old)
#include <iostream>
#include <vector>
#include <set>
using namespace std;
const int MAX_N = 1000010;
vector<int> adj[MAX_N];
vector<int> weights[MAX_N];
int n,m;
int deg[MAX_N];
void read_input()
{
cin >> n >> m;
for(int i=0; i<n; i++) {
deg[i] = 0;
}
for(int i=0; i<m; i++) {
int a,b,w;
cin >> a >> b >> w;
a--; b--;
adj[a].push_back(b);
weights[a].push_back(w);
deg[a]++;
adj[b].push_back(a);
weights[b].push_back(w);
deg[b]++;
}
}
bool is_visited[MAX_N];
int D[MAX_N];
const int INFINITY = 1000000000;
void dijkstra(int s)
{
for(int i=0; i<n; i++) {
is_visited[i] = false;
D[i] = INFINITY;
}
D[s] = 0;
set<pair<int,int>> Q;
Q.insert(make_pair(0,s));
for(int i=0; i<n; i++) {
int u;
do {
if(Q.empty())
return;
pair<int,int> uu = *(Q.begin());
Q.erase(Q.begin());
u = uu.second;
} while(is_visited[u]);
for(int j=0; j<deg[u]; j++) {
int v = adj[u][j]; // edge (u,v)
int w = weights[u][j];
//cout << D[u] << " " << w << " " << D[v] << endl;
if(D[u] + w < D[v]) {
D[v] = D[u] + w;
Q.insert(make_pair(D[v],v));
}
}
is_visited[u] = true;
}
}
int main()
{
read_input();
dijkstra(0);
cout << D[n-1] << endl;
}