Dijstra算法求最短路径
九度1008
题目描述:
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
输入:
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
输出:
输出 一行有两个数, 最短距离及其花费。
样例输入:
3 2
1 2 5 6
2 3 4 5
1 3
0 0
样例输出:
9 11
#include<stdio.h>
#include<iostream>
#include<vector>
using namespace std;
struct E {
int next;
int dis;
int price;
};
vector<E> edge[1000];
int main() {
int n, m;
int i, j;
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 && m == 0) break;
for (i = 1; i <= n; i++) {
edge[i].clear();
}
E temp;
while (m--) {
int a, b, d, p;
scanf("%d%d%d%d", &a, &b, &d, &p);
temp.dis = d;
temp.price = p;
temp.next = b;
edge[a].push_back(temp);
temp.next = a;
edge[b].push_back(temp);
}
int s, t;
scanf("%d%d", &s, &t);
bool mark[1000];
int dis[1000];
int pri[1000];
int newp;
for (i = 1; i <= n; i++) {
mark[i] = false;
dis[i] = -1;
pri[i] = 0;
}
mark[s] = true;
dis[s] = 0;
newp = s;
for (i = 1; i < n; i++) {
for (j = 0; j < edge[newp].size(); j++) {
int tn = edge[newp][j].next;
int td = edge[newp][j].dis;
int tp = edge[newp][j].price;
if (mark[tn] == true) continue;
if (dis[tn] == -1 || dis[newp] + td < dis[tn] || (dis[newp] + td == dis[tn] && pri[newp] + tp < pri[tn])) {
dis[tn] = dis[newp] + td;
pri[tn] = pri[newp] + tp;
}
}
int min = 123123123;
for (j = 1; j <= n; j++) {
if (mark[j] == true) continue;
if (dis[j] == -1) continue;
if (dis[j] < min) {
min = dis[j];
newp = j;
}
}
mark[newp] = true;
}
printf("%d %d", dis[t], pri[t]);
}
}
邻接矩阵表示
#include<stdio.h>
#include<iostream>
using namespace std;
int n, m;
bool mark[1001];
int s, e;
int dis[1001];
int edge[1001][1001];
int main() {
int i, j;
while (scanf("%d%d", &n, &m) != EOF) {
if (n == 0 && m == 0) break;
for (i = 1; i <= m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
edge[a][b] = edge[b][a] = c;
}
//初始化
for (i = 0; i < 1001; i++) {
dis[i] = 123123123;
mark[i] = false;
}
s = 1, e = n;
int min = 123123123;
int newp=1;
dis[1] = 0;
mark[1] = true;
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j++) {
if (mark[j] == false && min > dis[j]) {
min = dis[j];
newp = j;
}
}
mark[newp] = true;
for (j = 1; j <= n; j++) {
if (dis[j] > dis[newp] + edge[newp][j]) {
dis[j] = dis[newp] + edge[newp][j];
}
}
}
printf("%d", dis[n]);
}
}