原题地址:http://acm.hdu.edu.cn/showproblem.php?pid=3790
另外写文章之前偷懒一下,发现一个很好的入门python教程!:http://woodpecker.org.cn/abyteofpython_cn/chinese/
题意:在最短路径的前提下,添加了一个最短路径中权值最小的要求。
使用dijkstra算法。
注意此图是无向图,输入时保存最优的路径和权值。
具体细节在代码中:
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; #define INF 0x1f1f1f1f //防止不用fffffff防止溢出 #define min(a, b) a < b? a : b struct Cost { int l; int c; }; struct Low { int l; int c; }; Cost cost[1001][1001]; Low low[1001]; bool flag[1001]; int s; //出发点 void Dijkstra(int n) { int i, j, k; memset(flag, 0, sizeof(flag)); memset(low, 0x1f, sizeof(low)); flag[s] = 1; for(i = 1; i <= n; i++) { low[i].l = cost[s][i].l; //s到任意点的距离 low[i].c = cost[s][i].c; //s到任意点的花费 } low[s].l = 0; low[s].c = 0; for(i = 2; i < n; i ++) { int min = INF; int val = INF; for(j = 1; j <= n; j++) { if(flag[j] == 0 && low[j].l <= min)//到当前点距离 { if(low[j].l == min) { if(low[j].c < val) { val = low[j].c; k = j; } else //在length和value都相等的前提下,添加任何一个点都是一样的 continue; } else { min = low[j].l; val = low[j].c; k = j; } } } flag[k] = 1; for(j = 1; j <= n; j++) { if(flag[j] == 0 && cost[k][j].l + low[k].l <= low[j].l)//依据这个点修改最短路径 { if(cost[k][j].l + low[k].l < low[j].l) { low[j].l = low[k].l + cost[k][j].l; low[j].c = low[k].c + cost[k][j].c; } else { low[j].c = min(low[j].c, cost[k][j].c + low[k].c); } } } } } void ace() { int i, t;//work point int m, n; int a, b, d, p; while(scanf("%d%d", &n, &m)) { if(m == 0 && n == 0) break; memset(cost, INF, sizeof(cost)); for(i = 0; i < m; i++) { scanf("%d%d%d%d", &a,&b,&d,&p); if(cost[a][b].l > d) { cost[a][b].l = cost[b][a].l = d; cost[a][b].c = cost[b][a].c = p; } else if(cost[a][b].l == d && cost[a][b].c < p) { cost[a][b].c = cost[b][a].c = p; } else continue; } scanf("%d%d", &s, &t); Dijkstra(n); printf("%d %d\n", low[t].l, low[t].c); } } int main() { ace(); return 0; }
时间: 2024-10-15 18:37:00