本文出自:http://blog.csdn.net/svitter
原题地址: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;
}