1. 程式人生 > >Dijkstra及其堆優化

Dijkstra及其堆優化

樸素Dijkstra

#include<bits/stdc++.h>
using namespace std;
const int inf=9999999;
bool book[105];
int mp[105][105];
int dis[105];
int n,m;
void Dijkstra(int s){
    int start=s;
    memset(dis,inf,sizeof(dis));
    book[s]=1;
    for(int i=1;i<=n;i++) dis[i]=min(dis[i],mp[start][i]);
    int minn;
    for(int i=1;i<n;i++){
        minn=inf;
        for(int j=1;j<=n;j++)
            if(minn>dis[j]&&!book[j]){
                minn=dis[j];
                start=j;
            }
            book[start]=1;
        for(int j=1;j<=n;j++) dis[j]=min(dis[j],dis[start]+mp[start][j]);   
    }
}
int main(){
    int a,b,c,i,j;
    freopen("in.txt","r",stdin);
    cin>>n>>m>>j;
    memset(mp,inf,sizeof(mp));
    for(i=0;i<m;i++){
        cin>>a>>b>>c;
        mp[a][b]=c; mp[b][a]=c;
    }
    for(i=1;i<=n;i++) mp[i][i]=0;
    Dijkstra(j);
    for(i=1;i<=n;i++)
    cout<<dis[i]<<' ';
    cout<<endl;
    return 0;
}

Dijkstra堆優化

#include<bits/stdc++.h>
using namespace std;
struct node{
    int val,num;//val離出發點的最短距離,num該點編號 
    bool operator<(const node &a) const{//運算子過載 
      return val<a.val;
    }
};
int dis[1005];
vector<pair<int,int> > a[1005];//fi下一點編號,se到下一點的距離
priority_queue<node> dij;//最小堆 
int n,m,s;
int main(){
    int x,y,z;
    freopen("in.txt","r",stdin);
    cin>>n>>m>>s;
    for(int i=1;i<=n;i++) dis[i]=99999999;
    for(int i=1;i<=m;i++) {
        cin>>x>>y>>z;
        a[x].push_back(make_pair(y,z));//把相連的邊儲存
    }
    dis[s]=0;
    dij.push((node){0,s});
    while(!dij.empty()){
        int front=dij.top().num; dij.pop();
        for(int i=0;i<a[front].size();i++){//對front能到達的頂點進行鬆弛操作
            int to=a[front][i].first,va=a[front][i].second;
            if(dis[to]>dis[front]+va){
                dis[to]=dis[front]+va;
                dij.push((node){dis[to],to});
            }
        }
    }
    for(int i=1;i<=n;i++)
    cout<<dis[i]<<' ';
    cout<<endl;
    return 0;
}

測試樣例

4 6 1 
1 2 2 
2 3 2 
2 4 1 
1 3 5 
3 4 3 
1 4 4