- 该站点图是无向图
路径优先级:
(1)路径取得最小值 (Dijkstra()已经实现)
(2)在(1)都满足的条件下,PBMC发出的bike需要最小
(3)在(1)(2)都满足的条件下,带回来的bike需要最小;
- 先Dijkstra求出所有最短路径
- 再遍历每条路径,根据bike调整到half_full逻辑得出 PBMC 发出和带回 的 bike数,
- 更新得到最终的最优路径
#include <limits>
const int INF = numeric_limits<int>::max();
int C, N, Sp, M;
int perfect;
struct Edge
{
int to, weight;
};
int bikes_of_each_station[502] = {0};
// 根据前驱站点回溯获取完整路径
void get_all_paths(const vector<vector<int>> &predecessors,
vector<vector<int>> &all_paths,
vector<int> path,
int cur)
{
if(cur == 0)
{
// 回溯前驱站点得到的路径是逆序的,将其反转
reverse(path.begin(), path.end());
all_paths.push_back(path);
return;
}
for(auto p : predecessors[cur])
{
path.push_back(p);
get_all_paths(predecessors, all_paths, path, p);
path.pop_back();
}
}
void Dijkstra(const vector<vector<Edge>> &graph, int start)
{
// Dijkstra求所有最短路径并保存
vector<int> dist(N + 1, INF);
vector<bool> visited(N + 1, false);
vector<vector<int>> predecessors(N + 1);
dist[start] = 0;
for(int i = 0; i <= N; ++i)
{
int u = -1, minDist = INF;
for(int j = 0; j <= N; ++j)
{
if(!visited[j] && dist[j] < minDist)
{
minDist = dist[j];
u = j;
}
}
if(u == -1)
break;
visited[u] = true;
for(const auto &edge : graph[u])
{
int v = edge.to, w = edge.weight;
if(!visited[v])
{
int newDist = dist[u] + w;
if(newDist < dist[v])
{
dist[v] = newDist;
predecessors[v].clear();
predecessors[v].push_back(u);
}
else if(newDist == dist[v])
{
predecessors[v].push_back(u);
}
}
}
}
// 求出所有最短路径
vector<int> path = {Sp};
vector<vector<int>> all_paths;
get_all_paths(predecessors, all_paths, path, Sp);
// 找最佳路径,从PBMC开始,沿途调整,得到该路径需要的 送出 和 带回 的数量
int paths_count = all_paths.size();
int min_send = INF, min_back = INF, best_path_idx = 0;
for(int i = 0; i < paths_count; ++i)
{
vector<int> &cur_path = all_paths[i];
int path_len = cur_path.size();
int cur_take = 0, cur_send = 0, cur_back = 0;
for(int j = 1; j < path_len; ++j)
{
int sta = cur_path[j];
// 当前站大于perfect,需将其多余的带走
if(bikes_of_each_station[sta] > perfect)
{
cur_take += (bikes_of_each_station[sta] - perfect);
}
// 当前站小于perfect,需补充
else if(bikes_of_each_station[sta] < perfect)
{
int still_need = perfect - bikes_of_each_station[sta];
// 当前带的够补充
if(still_need <= cur_take)
{
cur_take -= still_need;
}
// 当前带的不够补充,需从源头增加送出
else
{
cur_send += (still_need - cur_take);
cur_take = 0;
}
}
}
// 最后带回的就是最后还有的
cur_back = cur_take;
// 优先选送出少的路径
if(cur_send < min_send)
{
min_send = cur_send;
min_back = cur_back;
best_path_idx = i;
}
// 再选最后带回少的路径
else if(cur_send == min_send)
{
if(cur_back < min_back)
{
min_send = cur_send;
min_back = cur_back;
best_path_idx = i;
}
}
}
// 打印最终的最佳路径
const vector<int> &p = all_paths[best_path_idx];
cout << min_send << " ";
for(int i = 0; i < p.size(); ++i)
{
cout << p[i];
if(i != p.size() - 1)
cout << "->";
}
cout << " " << min_back;
}
int main()
{
cin >> C >> N >> Sp >> M;
perfect = C / 2; // haff_full
for(int i = 1; i <= N; ++i)
cin >> bikes_of_each_station[i];
vector<vector<Edge>> graph(N + 1);
// 这里的站点图是 无向图!
auto add_edge = [&](int u, int v, int w){
graph[u].push_back({v, w});
graph[v].push_back({u, w});
};
int u, v, w;
for(int i = 0; i < M; ++i)
{
cin >> u >> v >> w;
add_edge(u, v, w);
}
Dijkstra(graph, 0);
return 0;
}

817

被折叠的 条评论
为什么被折叠?



