最短路徑--dijkstra

#include<queue>  
#include<map>  
#include<string>  
#include<iostream>  
#define INF 0x3f3f3f3f
#define maxn 1010
using namespace std;
//堆優化+vector<Edge> 
//類


struct qnode{//堆結點 
    int v;//頂點編號
    int dis;//頂點到起點的距離
    qnode(int v,int d):v(v),dis(d){
    } ;
    qnode(){

    };
    friend bool operator < (qnode a,qnode b){//默認<,最大堆
        return a.dis>b.dis;//最小堆 
    }
};

struct Edge{
    //從某個頂點出發到達點v花費c 
    int v;
    int c;
    Edge(int v,int c):v(v),c(c){
    };
}; 

class Graph{
    vector<Edge> E[maxn];//圖,鄰接表
    bool vis[maxn];
    int dis[maxn];
    int path[maxn];
    int n;
    int sc,di;
    public:
        void addEdge(int u,int v,int w){
            E[u].push_back(Edge(v,w));
        }
        void init(){

            int m;
            cin>>n>>m;
            int u,v,w;
            for(int i=0;i<m;i++){
                cin>>u>>v>>w;
                addEdge(u,v,w);
                //雙向 addEdge(v,u,w); 
            }
        }
        void init2(int start,int end){
            sc=start;
            di=end;
        }

        void dijkstra(){
            //init
            for(int i=1;i<=n;i++){
                dis[i]=INF;
                vis[i]=0; 
                path[i]=-1;
            }
            dis[sc]=0;
            //
            priority_queue<qnode> Q;
            Q.push(qnode(sc,0));
            //
            qnode tmp;
            while(!Q.empty()){
                //findmin
                tmp=Q.top();Q.pop();
                int u=tmp.v;
                if(vis[u])continue;
                vis[u]=true;
                //鬆弛
                for(int i=0;i<E[u].size();i++){//點u所有的出邊 
                    int v=E[u][i].v;
                    int cost=E[u][i].c;
                    if(!vis[v]&&dis[v]>dis[u]+cost){
                        dis[v]=dis[u]+cost;
                        path[v]=u;
                        //將被鬆弛過的點加入隊列
                        Q.push(qnode(v,dis[v]));  
                    }
                } 
            }

        } 

        void put(){
            for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
        }

};





int main(){
    Graph G;
    G.init();
    G.init2(1,5);
    G.dijkstra();
    G.put(); 

    return 0;
} 
#include<cstdio>  
#include<cstring>  
#include<algorithm>  
#include<queue>  
#include<map>  
#include<string>  
#include<iostream>  
#define INF 0x3f3f3f3f
#define maxn 1010
using namespace std;
//堆優化+vector<Edge> 

struct qnode{//堆結點 
    int v;//頂點編號
    int dis;//頂點到起點的距離
    qnode(int v,int d):v(v),dis(d){
    } ;
    qnode(){

    };
    friend bool operator < (qnode a,qnode b){//默認<,最大堆
        return a.dis>b.dis;//最小堆 
    }
};

struct Edge{
    //從某個頂點出發到達點v花費c 
    int v;
    int c;
    Edge(int v,int c):v(v),c(c){
    };
}; 

vector<Edge> E[maxn];//圖,鄰接表
void addEdge(int u,int v,int w){
    E[u].push_back(Edge(v,w));
}
bool vis[maxn];
int dis[maxn];
int path[maxn];
int n;
int sc,di;

void dijkstra(int sc){
    //init
    for(int i=1;i<=n;i++){
        dis[i]=INF;
        path[i]=-1;
    }
    dis[sc]=0;
    //
    priority_queue<qnode> Q;
    Q.push(qnode(sc,0));
    //
    qnode tmp;
    while(!Q.empty()){
        //findmin
        tmp=Q.top();Q.pop();
        int u=tmp.v;
        if(vis[u])continue;
        vis[u]=true;
        //鬆弛
        for(int i=0;i<E[u].size();i++){//點u所有的出邊 
            int v=E[u][i].v;
            int cost=E[u][i].c;
            if(!vis[v]&&dis[v]>dis[u]+cost){
                dis[v]=dis[u]+cost;
                path[v]=u;
                //將被鬆弛過的點加入隊列
                Q.push(qnode(v,dis[v]));  
            }
        } 
    }

} 
int main(){
    int m;
    cin>>n>>m;
    int u,v,w;
    for(int i=0;i<m;i++){
        cin>>u>>v>>w;
        addEdge(u,v,w);
        //雙向 addEdge(v,u,w); 
    }
    sc=1;//從1開始 
    dijkstra(sc);
    for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
    return 0;
} 




/*//最簡單的鄰接矩陣實現 
bool vis[maxn];
int path[maxn];
int g[maxn][maxn];
int dis[maxn];
int n,m;
int sc,di;//起點與終點; 

void dijkstra(int sc){
    //初始化dis[],vis[],path[]
    for(int i=0;i<n;i++){
        dis[i]=INF;
        vis[i]=0;
        path[i]=-1;
    }
    dis[sc]=0;
    // findmin
    while(1){
        int mindis=INF,minv=-1;
        for(int j=0;j<n;j++){
            if(!vis[j]&&dis[j]<mindis){
                mindis=dis[j];
                minv=j;
            }
        }
        //找不到未在集合中的點則退出(所有點都包含進集合) 
        if(minv==-1) break;
        vis[minv]=1;
        cout<<"minv= "<<minv<<endl;
        //鬆弛操作 (對不在集合中的點) 
         for(int i=0;i<n;i++){
            if(!vis[i]&&dis[i]>dis[minv]+g[minv][i]){
                cout<<"A";
                dis[i]=dis[minv]+g[minv][i];
                path[i]=minv;
            }
         }
    }
}
int main(){
    cin>>n>>m;
    //定義頂點編號從0--n-1
    int u,v,w;
    //初始化圖g
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            i==j?g[i][j]=0:g[i][j]=INF;
        }
    } 
    for(int i=0;i<m;i++){
        cin>>u>>v>>w;
        //有向圖
        g[u-1][v-1]=w; 
    } 
    sc=0;
    dijkstra(sc);
    for(int i=0;i<n;i++){
        cout<<dis[i]<<" ";
    }
    return 0;
} 

 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章