用的spfa的思想写的,我感觉用一个标记数组flag[]来标志是否在队列中,好像不是很有用啊,只要做了松弛操作,我感觉都应该入队才是吧= =。这道题目就是更新路径的时候顺便更新一下花费。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f;
const int MAX = 1e3 + 5;
int d[MAX], p[MAX];//, flag[MAX];
struct EDGE
{
int to, cost, price;
EDGE(int a = 0, int b = 0, int c = 0)
: to(a), cost(b), price(c)
{}
};
vector<EDGE> que[MAX];
queue<int> coor;
int main()
{
int n, m;
while (scanf("%d%d", &n, &m))
{
if (n == 0 && m == 0)
{
break;
}
for (int i = 1; i <= n; ++i)
que[i].clear();
int t_from, t_to, t_cost, t_price;
//memset(flag, 0, sizeof(flag));
memset(d, INF, sizeof(d));
memset(p, INF, sizeof(p));
for (int i = 0; i < m; ++i)
{
scanf("%d%d%d%d", &t_from, &t_to, &t_cost, &t_price);
que[t_from].push_back(EDGE(t_to, t_cost, t_price));
que[t_to].push_back(EDGE(t_from, t_cost, t_price));
}
int st, ed;
scanf("%d%d", &st, &ed);
// flag[st] = 1;
d[st] = 0;
p[st] = 0;
coor.push(st);
int res = INF;
while (!coor.empty())
{
int t_coor = coor.front();
coor.pop();
//flag[t_coor] = 0;
int lenth = que[t_coor].size();
for (int i = 0; i < lenth; ++i)
{
EDGE t_edge = que[t_coor][i];
if (d[t_edge.to] > d[t_coor] + t_edge.cost)
{
d[t_edge.to] = d[t_coor] + t_edge.cost;
// printf("from(%d) to(%d)\n", t_coor, t_edge.to);
// printf("shortest path = %d price = %d\n", d[ed], p[ed]);
// if (p[t_edge.to] >= p[t_coor] + t_edge.price)
p[t_edge.to] = p[t_coor] + t_edge.price;
//printf("now price = %d\n", p[ed]);
// res = min(res, p[ed]);
coor.push(t_edge.to);
}
else if (d[t_edge.to] == d[t_coor] + t_edge.cost && p[t_edge.to] > p[t_coor] + t_edge.price)
p[t_edge.to] = p[t_coor] + t_edge.price;
}
}
printf("%d %d\n", d[ed], p[ed]);
}
return 0;
}