http://pat.zju.edu.cn/contests/pat-a-practise/1030
单源最短路径,多个权值的情况。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
#define INF 0x0FFFFFFF
struct Node{
int dis, cost;
};
Node tmap[505][505];
int n, m, s, d;
struct Ans{
int dist, cost;
vector<int>path;
};
void diji(int s, int d)
{
Ans result[505];
int i;
bool isVisted[505];
memset(isVisted, 0, sizeof(isVisted));
for(i = 0; i < n; i ++)
{
result[i].dist = tmap[s][i].dis;
result[i].cost = tmap[s][i].cost;
result[i].path.clear();
if(result[i].dist < INF && i != s) result[i].path.push_back(i);
}
result[s].dist = 0;
result[s].path.push_back(s);
isVisted[s] = true;
int CASE = n;
while(--CASE)
{
int min_dist = INF, min_cost = INF, index;
for(i = 0; i < n; i ++)
{
if(!isVisted[i] && (result[i].dist < min_dist ||
(result[i].dist == min_dist && result[i].cost < min_cost)))
{
min_dist = result[i].dist;
min_cost = result[i].cost;
index = i;
}
}
isVisted[index] = true;
if(index == d)
{
cout<<s;
for(int x = 0; x < result[index].path.size(); x ++) cout<<' '<<result[index].path[x];
cout<<' '<<min_dist<<' '<<min_cost<<endl;
return;
}
for(i = 0; i < n; i ++)
{
if(!isVisted[i])
{
if( (min_dist + tmap[index][i].dis < result[i].dist) ||
( (min_dist + tmap[index][i].dis == result[i].dist) &&
min_cost + tmap[index][i].cost < result[i].cost) )
{
result[i].dist = min_dist + tmap[index][i].dis;
result[i].cost = min_cost + tmap[index][i].cost;
result[i].path.clear();
for(int k = 0; k < result[index].path.size(); k ++)
result[i].path.push_back(result[index].path[k]);
result[i].path.push_back(i);
}
}
}
}
}
int main()
{
int i, j, a, b, x;
scanf("%d %d %d %d", &n, &m, &s, &d);
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
if(i != j)
{
tmap[i][j].dis = tmap[j][i].dis = INF;
tmap[i][j].cost = tmap[j][i].cost = INF;
}
}
for(i = 0; i < m; i ++)
{
scanf("%d %d %d %d", &a, &b, &j, &x);
tmap[a][b].cost = tmap[b][a].cost = x;
tmap[a][b].dis = tmap[b][a].dis = j;
}
diji(s, d);
return 0;
}