step6 演算法 HDU3790 最短路徑問題【Dijkstra演算法】
阿新 • • 發佈:2019-01-25
思路:迪傑斯特拉演算法
#include<iostream> #include<vector> #include<queue> #define inf 0x3f3f3f3f #define maxn 1005 using namespace std; class Edge{ public: int v,cost,pay;//cost代表長度、 pay代表花費 Edge(){ } Edge(int vv,int cc,int pp){ v=vv; cost=cc; pay=pp; } }; class Node{ public: int v; int cost; Node (int vv=0,int c=0){ v=vv; cost=c; } //優先順序佇列將使用下面的過載 friend bool operator<(Node n1,Node n2){ return n1.cost>n2.cost; } }; vector<Edge>g[maxn]; //無向圖 bool marked[maxn]; //D演算法中每個頂點僅處理一遍 int disto[maxn]; //出發點到某點距離 int costo[maxn]; //接通改點需要增加的邊的花費 int n,m; void dijkstra(int s,int u){ //初始化 for(int i=0;i<=n;i++) { marked[i]=false; disto[i]=inf; costo[i]=inf; } costo[s]=disto[s]=0; priority_queue<Node>pq;//儲存<v,disto[v]>且按disto[v]升序排列 pq.push(Node(s,0)); Node tmp; while(!pq.empty()){ tmp=pq.top(); pq.pop(); int v=tmp.v; if(marked[v])continue; if(v==u)return; marked[v]=true; int len=g[v].size(); for(int i=0;i<len;i++){ int vv=g[v][i].v; if(marked[vv])continue; int cost=g[v][i].cost; int pay=g[v][i].pay; //判斷已經算得的到另一個點的距離是否需要迭代, //即同現有點加上現有點到另一個點的消耗 比較 if(disto[vv]>disto[v]+cost){ disto[vv]=disto[v]+cost; costo[vv]=costo[v]+pay; //增加的內容 pq.push(Node(vv,disto[vv])) ; } //增加的內容 //加入點vv時若出現多種距離相同的方案,選取新邊最小的那個 if(disto[vv]==disto[v]+cost){ costo[vv]=min(costo[vv],costo[v]+pay); } } } } int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); while(cin>>n>>m&&n!=0){ for(int i=0;i<=n;i++)g[i].clear(); for(int i=0;i<m;i++){ int a,b,c,d; cin>>a>>b>>c>>d; Edge edge; edge.v=b; edge.cost=c; edge.pay=d; g[a].push_back(edge); edge.v=a; g[b].push_back(edge); } int a,b;cin>>a>>b; dijkstra(a,b); cout<<disto[b]<<" "<<costo[b]<<endl; } return 0; }