最短路径问题
问题链接->点击这里
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<iostream>
#include<memory.h>
using namespace std;
#define INF 0x3f3f3f
struct Node {
int dis, expense;
bool operator < ( const Node &a ) const {
if ( dis != a.dis ) {
return dis < a.dis;
}
else return expense < a.expense;
}
Node operator + ( Node a ) const {
a.dis += dis;
a.expense += expense;
return a;
}
} dis[1005][1005], mindis[1005];
int flag[1005];
void initialization ( int n ) {
int i, j;
for ( i = 1; i <= n; i ++ ) {
for ( j = 1; j <= n; j ++ ) {
if ( i == j ) {
dis[i][j].dis = 0;
}
else dis[i][j].dis = INF;
dis[i][j].expense = 0;
}
}
memset ( flag, 0, sizeof ( flag ) );
}
void dijkstra ( int n, int s ) {
int i, k;
Node minn;
for ( i = 1; i <= n; i ++ ) {
mindis[i] = dis[s][i];
}
flag[s] = 1;
i = s;
while ( i && i <= n ) {
k = 0;
minn.dis = INF;
minn.expense = 0;
for ( int j = 1; j <= n; j ++ ) {
if ( !flag[j] ) {
mindis[j] = min ( mindis[j], dis[i][j] + mindis[i] );
if ( mindis[j] < minn ) {
minn = mindis[j];
k = j;
}
}
}
flag[k] = 1;
i = k;
}
}
int main ( ) {
int n, m, s, t, a, b, d, p;
while ( scanf ( "%d%d", &n, &m ), m || n ) {
initialization ( n );
for ( int i = 1; i <= m; i ++ ) {
scanf ( "%d%d%d%d", &a, &b, &d, &p );
//一定要比较!!!!!!
if ( dis[a][b].dis > d ) {
dis[a][b].dis = dis[b][a].dis = d;
dis[a][b].expense = dis[b][a].expense = p;
}
else if ( dis[a][b].dis == d && dis[a][b].expense > p ) {
dis[a][b].expense = dis[b][a].expense = p;
}
}
scanf ( "%d%d", &s, &t );
dijkstra ( n, s );
printf ( "%d %d\n", mindis[t].dis, mindis[t].expense );
}
return 0;
}
/*
4 5
1 2 10 5
1 3 10 4
2 3 5 3
2 4 50 100
3 4 70 1
1 4
4 5
1 2 10 5
1 3 10 4
2 3 5 3
2 4 50 100
3 4 70 1
4 3
*/