ผลต่างระหว่างรุ่นของ "Algo lab/dijkstra"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
(สร้างหน้าด้วย "== Slower version == <syntaxhighlight lang="cpp"> #include <iostream> #include <vector> using namespace std; const int MAX_N = 1000010; vector<int> ad...")
 
 
(ไม่แสดง 2 รุ่นระหว่างกลางโดยผู้ใช้คนเดียวกัน)
แถว 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;
+
        u = x;
du = D[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;
+
        D[v] = D[u] + w;
 
       }
 
       }
 
     }
 
     }
แถว 84: แถว 84:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== Fast version ==
+
== 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) ==
 +
<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> 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;
 +
}
 +
</syntaxhighlight>
 +
 
 +
== Fast version (old) ==
 
<syntaxhighlight lang="cpp">
 
<syntaxhighlight lang="cpp">
 
#include <iostream>
 
#include <iostream>
แถว 142: แถว 291:
 
     do {
 
     do {
 
       if(Q.empty())
 
       if(Q.empty())
return;
+
        return;
 
       pair<int,int> uu = *(Q.begin());
 
       pair<int,int> uu = *(Q.begin());
 
       Q.erase(Q.begin());
 
       Q.erase(Q.begin());
แถว 154: แถว 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;
+
        D[v] = D[u] + w;
  
Q.insert(make_pair(D[v],v));
+
        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;
}