//dfs
#include<cstdio>
#include<algorithm>
#include<list>
using namespace std;
bool visited[500];
int pre[500]; //从哪个城市来
int cityNum, pathNum, start, dest;
int inf = 0x7fffffff;
int minCost = inf, minDis = inf;
list<int> minPath;
struct node {
int dis, cost;
}map[500][500];
void recordPath() {
int pos = dest;
while (pos != -1) {
minPath.push_front(pos);
pos = pre[pos];
}
}
void dfs(int pos, int curCost, int curDis) {
if (curDis > minDis) {
return;
}
if (pos == dest) {
if (curDis < minDis || curDis == minDis && curCost < minCost) {
minDis = curDis;
minCost = curCost;
minPath.clear();
recordPath();
}
return;
}
for (int i = 0;i < cityNum;i++) {
if (map[pos][i].dis != inf && !visited[i]) {
visited[i] = true;
pre[i] = pos;
dfs(i, curCost + map[pos][i].cost, curDis + map[pos][i].dis);
visited[i] = false;
}
}
}
int main() {
scanf("%d %d %d %d", &cityNum, &pathNum, &start, &dest);
//fill(map[0], map[0] + cityNum * cityNum, inf);
pre[start] = -1;
visited[start] = true;
for (int i = 0;i < cityNum;i++) {
for (int j = 0;j < cityNum;j++) {
map[i][j].dis = inf;
}
}
for (int i = 0;i < pathNum;i++) {
int c1, c2, dis, cost;
scanf("%d %d %d %d", &c1, &c2, &dis, &cost);
map[c1][c2].cost = cost;
map[c1][c2].dis = dis;
map[c2][c1].cost = cost;
map[c2][c1].dis = dis;
}
dfs(start, 0, 0);
for (list<int>::iterator it = minPath.begin();it != minPath.end();it++) {
printf("%d ", *it);
}
printf("%d %d", minDis, minCost);
}
//dijkstra
#include<cstdio>
#include<algorithm>
#include<list>
using namespace std;
bool visited[500];
int map[500][500], cost[500][500];
int pre[500];
int dis[500];
int curCost[500];
const int inf = 0x7fffffff;
int main() {
int cityNum, pathNum, start, dest;
scanf("%d %d %d %d", &cityNum, &pathNum, &start, &dest);
fill(map[0], map[0] + 500 * 500, inf);
for (int i = 0;i < pathNum;i++) {
int c1, c2, d, c;
scanf("%d %d %d %d", &c1, &c2, &d, &c);
map[c1][c2] = d;
map[c2][c1] = d;
cost[c1][c2] = c;
cost[c2][c1] = c;
}
fill(dis, dis + 500, inf);
fill(curCost, curCost + 500, 0);
dis[start] = 0;
for (int i = 0;i < cityNum;i++) {
//选出距离最小的
int u = -1, d = inf;
for (int j = 0;j < cityNum;j++) {
if (!visited[j] && dis[j] < d) {
u = j;
d = dis[j];
}
}
if (u == -1)
break;
visited[u] = true;
for (int v = 0;v < cityNum;v++) {
if (!visited[v] && map[u][v] != inf) {
if (dis[u] + map[u][v] < dis[v]) {
dis[v] = dis[u] + map[u][v];
pre[v] = u;
curCost[v] = curCost[u] + cost[u][v];
}
else if (dis[u] + map[u][v] == dis[v]) {
if (curCost[u] + cost[u][v] < curCost[v]) {
pre[v] = u;
curCost[v] = curCost[u] + cost[u][v];
}
}
}
}
}
pre[start] = -1;
list<int> minPath;
for (int pos = dest; pos != -1; pos = pre[pos]) {
minPath.push_front(pos);
}
for (list<int>::iterator it = minPath.begin();it != minPath.end();it++) {
printf("%d ", *it);
}
printf("%d %d", dis[dest], curCost[dest]);
}
二刷
#include<iostream>
#include<list>
#include<algorithm>
using namespace std;
const int inf = 0x7fffffff;
int cityNum, highwayNum, source, destination;
int map[500][500], cost[500][500], dist[500], totalCost[500], pre[500];
bool visited[500];
list<int> minPath;
int main() {
fill(pre, pre + 500, -1);
fill(map[0], map[0] + 500 * 500, inf);
fill(cost[0], cost[0] + 500 * 500, inf);
fill(dist, dist + 500, inf);
fill(totalCost, totalCost + 500, inf);
cin >> cityNum >> highwayNum >> source >> destination;
for (int i = 0;i < highwayNum;i++) {
int c1, c2, d, c;
cin >> c1 >> c2 >> d >> c;
map[c1][c2] = d;
map[c2][c1] = d;
cost[c1][c2] = c;
cost[c2][c1] = c;
}
dist[source] = 0;
totalCost[source] = 0;
for (int i = 0;i < cityNum;i++) {
int u = -1, minDist = inf;
for (int j = 0;j < cityNum;j++) {
if (!visited[j] && minDist > dist[j]) {
u = j;
minDist = dist[j];
}
}
if (u == destination || u == -1)
break;
visited[u] = true;
for (int v = 0; v < cityNum;v++) {
if (!visited[v] && map[u][v] != inf) {
if (dist[u] + map[u][v] < dist[v] || dist[u] + map[u][v] == dist[v] && totalCost[u] + cost[u][v] < totalCost[v]) {
dist[v] = dist[u] + map[u][v];
totalCost[v] = totalCost[u] + cost[u][v];
pre[v] = u;
}
}
}
}
int cur = destination;
while (cur != -1) {
minPath.push_front(cur);
cur = pre[cur];
}
for (int e : minPath)
cout << e << " ";
cout << dist[destination] << " " << totalCost[destination];
}