这题和1018很像,换了写法,先找最短路再dfs,写了下dijkstra算法,有点生疏。
快复试了,加油!
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
struct edge
{
bool flag = false;
int l;
int c;
};
edge map[505][505];
vector<int> pre[505];
int ans[505];
int tempans[505];
int num = 0;
int cost = -1;
int res = -1;
bool flag[505];
void init()
{
memset(map, 0, sizeof(map));
for (int i = 0; i < 505; i++)
{
pre[i].clear();
}
}
void dijkstra(int s, int d, int n)
{
int dis[505];
memset(flag, 0, sizeof(flag));
for (int i = 0; i < n; i++)
dis[i] = 505 * 505;
for (int i = 0; i < n; i++)
{
if (map[s][i].flag != 0)
{
dis[i] = map[s][i].l;
pre[i].push_back(s);
}
}
flag[s] = 1;
while (!flag[d])
{
int min = 505 * 505;
int p;
for (int i = 0; i < n; i++)
{
if (min > dis[i]&&!flag[i])
{
min = dis[i];
p = i;
}
}
flag[p] = 1;
for (int i = 0; i < n; i++)
{
if (!flag[i] && map[p][i].flag != 0)
{
if (dis[i] > map[p][i].l + dis[p])
{
dis[i] = map[p][i].l + dis[p];
pre[i].clear();
pre[i].push_back(p);
}
else if (dis[i] == map[p][i].l + dis[p])
{
pre[i].push_back(p);
}
}
}
}
res = dis[d];
}
void dfs(int cnt,int c,int s, int d)
{
if (s == d)
{
if (cost > c||cost == -1)
{
int temp = 1;
ans[0] = s;
for (int i = cnt-1; i >= 0; i--)
{
ans[temp++] = tempans[i];
}
num = temp;
cost = c;
}
}
else
{
for (int i = 0; i < pre[d].size(); i++)
{
int temp = pre[d][i];
if (!flag[temp])
{
flag[temp] = 1;
c += map[temp][d].c;
tempans[cnt + 1] = temp;
dfs(cnt + 1, c, s, temp);
flag[temp] = 0;
c -= map[temp][d].c;
}
}
}
}
int main()
{
int n, m, s, d;
while (~scanf("%d%d%d%d", &n, &m, &s, &d))
{
init();
int c1, c2, dis, c;
for (int i = 0; i < m; i++)
{
scanf("%d%d%d%d", &c1, &c2, &dis, &c);
map[c1][c2].l = map[c2][c1].l = dis;
map[c1][c2].c = map[c2][c1].c = c;
map[c1][c2].flag = 1;
map[c2][c1].flag = 1;
}
dijkstra(s, d, n);
memset(ans, 0, sizeof(ans));
num = 0;
cost = -1;
memset(flag, 0, sizeof(flag));
tempans[0] = d;
dfs(0, 0, s, d);
for (int i = 0; i < num; i++)
{
printf("%d ", ans[i]);
}
printf("%d %d\n", res, cost);
}
return 0;
}