ホームに戻る
ダイクストラ

// priority_queue を使う場合と使わない場合がある。
// 計算量が違うので使い分けること。
// 負のコストがある場合はベルマン・フォードを使う。

// priority_queue を使わない場合。計算量O(V^2)。
// グラフにおいて start 地点から i 地点への最小移動コストを求める。
// m[i][j] に i から j へ移動するコストを入れる。
// 双方向リストの場合 m[i][j] と m[j][i] に値を入れること。
// たどり着けない場合には INF を入れる。
// MAX_V に最大のノード数を設定。INF は十分大きな値。
// m[i][j] をセットし dijk(start,V)で呼ぶ。
// start はスタート地点、V はノードの数。
// 答えは mn[i] に存在する。
// 負のコストは禁止。

#define MAX_V 50
#define INF 1000000000

int m[MAX_V][MAX_V];
int mn[MAX_V];
int dijflag[MAX_V];

void dijk(int start, int V){
  for(int i = 0; i < MAX_V; i++)mn[i] = INF;
  for(int i = 0; i < MAX_V; i++)dijflag[i] = 0;
  mn[start] = 0;
  for(;;){
    int v = -1;
    for(int i = 0; i < V; i++){
      if(dijflag[i] == 0){
        if(v == -1){
          v = i;
        }
        else{
          if(mn[i] < mn[v]){
            v = i;
          }
        }
      }
    }
    if(v == -1)break;
    dijflag[v] = 1;
    for(int i = 0; i < V; i++){
      if(mn[i] > mn[v] + m[v][i]){
        mn[i] = mn[v] + m[v][i];
      }
    }
  }
}

// priority_queue を使う場合。計算量O(Elog(V))。
// グラフにおいて start 地点から i 地点への最小移動コストを求める。
// ae(from,to,cost)でエッヂを追加。
// MAX_V に最大のノード数を設定。INF は十分大きな値。
// すべてのエッヂを追加し dijk(start,V)を呼ぶ。
// start はスタート地点、V はノードの数。
// 答えは mn[i] に存在する。
// 負のコストは禁止。

#define MAX_V 200002
#define INF 1000000000

struct edge{int to, cost;};
typedef pair<int,int> P;

vector<edge> G[MAX_V];
int mn[MAX_V];

void ae(int from, int to, int cost){
  edge e = {to,cost};
  G[from].push_back(e);
}

void dijk(int start, int V){
  priority_queue<P, vector<P>, greater<P> > que;
  for(int i = 0; i < V; i++)mn[i] = INF;
  mn[start] = 0;
  que.push(P(0,start));
  while(!que.empty()){
    P p = que.top(); que.pop();
    int v = p.second;
    if(mn[v]<p.first)continue;
    for(int i = 0; i < G[v].size(); i++){
      edge e = G[v][i];
      if(mn[e.to] > mn[v]+e.cost){
        mn[e.to] = mn[v]+e.cost;
        que.push(P(mn[e.to],e.to));
      }
    }
  }
}

// 値を持つ場合

#define MAX_V 50
#define MAX_STATE 100
#define INF 1000000000

struct edge{int to, cost;};
#define P pair<int,int>
#define Q pair<int,pair<int,int> >

vector<edge> G[MAX_V];
int mn[MAX_V][MAX_STATE];

void ae(int from, int to, int cost){
  edge e = {to,cost};
  G[from].push_back(e);
}

void dijk(int start, int V){
  priority_queue<Q,vector<Q>,greater<Q> > que;
  mn[start][0] = 0;
  que.push(Q(0,P(start,0)));
  while(!que.empty()){
    Q node = que.top();
    que.pop();
    int num = node.se.fi;
    int state = node.se.se;
    if(mn[num][state]<node.fi)continue;
    rep(i,0,v[num].sz){
      edge e = v[num][i];
      if(mn[e.to][state]>mn[num][state]+e.cost){
        mn[e.to][state] = mn[num][state]+e.cost;
        que.push(Q(mn[e.to][state],P(e.to,state)));
      }
    }
  }
}
inserted by FC2 system