最短路徑問題(多權值最短路)(D)
阿新 • • 發佈:2018-11-29
最短路徑問題
給你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;
}