思路
首先用Dijkstra算法求出起点到其他所有站点的最短路径和距离。然后使用深度优先搜索遍历所有最短路径,并计算在该路径下的send和collect数量,最后找到一组最优的send和collect,输出方案。
注意:1.每次只走一趟,过程中需要send和collect,不是来回走两趟。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
#define MaxN 501
#define INT_MAX 1e9
int g[MaxN][MaxN];
bool visited[MaxN];
int dist[MaxN];
vector<int> pre[MaxN];
int state[MaxN];
void dijkstra(int n) {
for (int i = 0; i < n; i++) {
if (g[0][i] != INT_MAX) {
dist[i] = g[0][i];
pre[i].push_back(0);
}
}
visited[0] = true;
for (int i = 0; i < n - 1; i++) {
int min = INT_MAX;
int k = -1;
for (int j = 0; j < n; j++) {
if (!visited[j] && dist[j] < min) {
min = dist[j];
k = j;
}
}
visited[k] = true;
if (k == -1) {
break;
}
for (int i = 0; i < n; i++) {
if (!visited[i] && dist[k] + g[k][i] < dist[i]) {
dist[i] = dist[k] + g[k][i];
pre[i].clear();
pre[i].push_back(k);
}
else if (!visited[i] && dist[k] + g[k][i] == dist[i]) {
pre[i].push_back(k);
}
}
}
}
void calcuSendAndCollect(vector<int> path, int half_c, int& send, int& collect) {
for (int i = path.size() - 1; i >= 0; i--) {
int num = path[i];
if (state[num] > half_c) {
collect += (state[num] - half_c);
}
if (state[num] < half_c) {
if ((half_c - state[num]) < collect) {
collect -= (half_c - state[num]);
}
else {
collect = 0;
send += ((half_c - state[num]) - collect);
}
}
cout << "c: " << state[num];
cout << " send: " << send;
cout << " collect: " << collect;
cout << endl;
}
}
void dfs(int& best_send, int& best_collect, int c_max, int curr, vector<int> path, vector<int>& best_path) {
if (curr == 0) {
int send = 0;
int collect = 0;
calcuSendAndCollect(path, c_max / 2, send, collect);
if ((send < best_send)|| (send == best_send && collect < best_collect)) {
best_send = send;
best_collect = collect;
best_path = path;
}
return;
}
else {
path.push_back(curr);
for (int i = 0; i < pre[curr].size(); i++) {
dfs(best_send, best_collect, c_max, pre[curr][i], path, best_path);
}
}
}
int main() {
// 初始化边距
fill(g[0], g[0] + MaxN * MaxN, INT_MAX);
// 初始化起点到其他点的最短距离
fill(dist, dist + MaxN, INT_MAX);
// 初始化起点到其他点的最短距离
fill(visited, visited + MaxN, false);
int c_max = 0;
int n = 0;
int ind = 0;
int num_of_road = 0;
cin >> c_max >> n >> ind >> num_of_road;
for (int i = 0; i < n; i++) {
cin >> state[i + 1];
}
for (int i = 0; i < num_of_road; i++) {
int m, n;
cin >> m >> n;
cin >> g[m][n];
g[n][m] = g[m][n];
}
dijkstra(n + 1);
int best_send = 1e9;
int best_collect = 1e9;
vector<int> path;
vector<int> best_path;
dfs(best_send, best_collect, c_max, ind, path, best_path);
cout << best_send << " " << 0;
for (int i = best_path.size() - 1; i >= 0; i--) {
cout << "->" << best_path[i];
}
cout << " " << best_collect << endl;
}