最短路径问题
给你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
需要用到优先队列
再开一个val数组记录花费
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 0x3f3f3f3f;
int m, n;
int a, b, d, p;
int s, t;
int tot;
int dis[maxn];
int vis[maxn];
int val[maxn];
int head[maxn];
struct node{
int to;
int next;
int l;
int v;
node() {}
node(int z, int x, int c, int y) : to(z), next(x), l(c), v(y) {}
} edge[maxn];
void edgeadd(int a, int b, int d, int p){
edge[tot] = node(b, head[a], d, p);
head[a] = tot++;
edge[tot] = node(a, head[b], d, p);
head[b] = tot++;
}
void init(){
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
memset(dis, inf, sizeof(dis));
memset(val, inf, sizeof(val));
tot = 0;
}
struct heapnode{
int di, li, u;
heapnode() {}
heapnode(int a, int b, int c) : di(a), li(b), u(c) {}
bool operator < (const heapnode &rhs)const//重载
{
if(di == rhs.di)
return li > rhs.li;//按花费从小到大排
return di > rhs.di;//按距离从小到大排
}
};
void dijktra(int str){
priority_queue <heapnode> q;
q.push(heapnode(0, 0, str));
dis[str] = 0;
val[str] = 0;
while(!q.empty()){
heapnode w = q.top();
q.pop();
int f = w.u;
if(vis[f])
continue;
vis[f] = 1;
for(int i = head[f]; i != -1; i = edge[i].next){
int k = edge[i].to;
if(dis[k] >= dis[f] + edge[i].l){
if(dis[k] == dis[f] + edge[i].l){
if(val[k] <= val[f] + edge[i].v)
continue;
}
dis[k] = dis[f] + edge[i].l;
val[k] = val[f] + edge[i].v;
q.push(heapnode(dis[k], val[k], k));
}
}
}
}
int main(){
ios::sync_with_stdio(false);
while(cin >> n >> m && n != 0 && m != 0){
init();
for(int i = 0; i < m; i++){
cin >> a >> b >> d >> p;
edgeadd(a, b, d, p);
}
cin >> s >> t;
dijktra(s);
cout << dis[t] << " " << val[t] << endl;
}
return 0;
}