1. 程式人生 > >最短路徑問題(多權值最短路)(D)

最短路徑問題(多權值最短路)(D)

最短路徑問題

給你n個點,m條無向邊,每條邊都有長度d和花費p,給你起點s終點t,要求輸出起點到終點的最短距離及其花費,如果最短距離有多條路線,則輸出花費最少的。
Input
輸入n,m,點的編號是1~n,然後是m行,每行4個數 a,b,d,p,表示a和b之間有一條邊,且其長度為d,花費為p。最後一行是兩個數 s,t;起點s,終點。n和m為0時輸入結束。
(1<n<=1000, 0<m<100000, s != t)
Output
輸出 一行有兩個數, 最短距離及其花費。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11

多權值最短路,用Dijkstra的優化版本,根據不同權值改改優先順序佇列的運算子過載

#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct node{
	int v,d,p;
	node(){}
	node(int vv,int dd,int pp){
		v=vv;
		d=dd;
		p=pp;
	}
}; 
struct Node{
	int u,d,p;
	Node(){}
	Node(int uu,int dd,int pp){
		u=
uu; d=dd; p=pp; } bool operator<(const Node other)const{ if(d!=other.d) return d>other.d;//距離短的優先 else return p>other.p;//如果距離一樣,花費少的優先 } }; const int maxn=1005; const int Inf=0x3f3f3f3f; int n,m,s,t; vector<node> G[maxn]; bool book[maxn]; int dis[maxn],cost[maxn]; void Dijkstra(){ priority_queue<
Node> q; for(int i=1;i<=n;i++){ dis[i]=Inf,cost[i]=Inf; book[i]=false; } dis[s]=0,cost[s]=0; q.push(Node(s,dis[s],cost[s])); while(!q.empty()){ Node temp=q.top(); q.pop(); int u=temp.u; if(book[u]) continue; book[u]=true; for(int i=0;i<G[u].size();i++){ node tmp=G[u][i]; int v=tmp.v; int d=tmp.d; int p=tmp.p; if(dis[v]>=dis[u]+d){ //注意是大於等於(因為是如果最短距離一樣,輸出花費最少的) dis[v]=dis[u]+d; cost[v]=cost[u]+p; q.push(Node(v,dis[v],cost[v])); } } } printf("%d %d\n",dis[t],cost[t]); } int main(){ int a,b,d,p; while(scanf("%d%d",&n,&m)){ if(n==0&&m==0) break; for(int i=1;i<=n;i++) G[i].clear(); for(int i=1;i<=m;i++){ scanf("%d%d%d%d",&a,&b,&d,&p); G[a].push_back(node(b,d,p)); G[b].push_back(node(a,d,p)); } scanf("%d%d",&s,&t); Dijkstra(); } return 0; }