版权声明:本文为博主原创文章,若需要引用、转载,只需注明来源及原文链接,若有错误,欢迎纠正。 https://blog.csdn.net/u014137295/article/details/87162524
Problem Description
给你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
解题思路:
比正常的最短路,多了,距离相同情况下在比较价格
代码:
#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
struct r{
int a,t,p;
bool operator <(const r &b)const{
return t==b.t?p>b.p:t>b.t;
}
};
bool cmp(r a,r b){
return a.p<b.p;
}
vector<r>e[maxn];
int d[maxn],pr[maxn];
void dijkstra(int s,int t){
priority_queue<r>q;
q.push({d[s],s,pr[s]});
d[s]=0;
while(!q.empty()){
int now=q.top().t; q.pop();
for(unsigned int i=0;i<e[now].size();++i){
int v=e[now][i].a;
if(d[v]>d[now]+e[now][i].t){
d[v]=d[now]+e[now][i].t;
pr[v]=pr[now]+e[now][i].p;
q.push({d[v],v,pr[v]});
}
}
}
printf("%d %d\n",d[t],pr[t]);
}
int main(){
int n,m,a,b,c,p;
while(1){
n=read(),m=read();
if(!n&&!m)break;
for(int i=0;i<maxn;++i)e[i].clear(),d[i]=1e9,pr[i]=0;
for(int i=0;i<m;++i){
scanf("%d%d%d%d",&a,&b,&c,&p);
e[b].push_back({a,c,p});
e[a].push_back({b,c,p});
}
int s,t;
scanf("%d%d",&s,&t);
dijkstra(s,t);
}
return 0;
}