牛课网的所有测试案例可以通过,但是可能会卡在PAT的第7个测试点。因为Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC.
即相同路径长度排序应该是先比较send较小的情况,其次在比较back较小的情况。
思路
- Dijkstra+dfs
- 使用Dijkstra搜得所有最短路径
- 遍历最短路径,选择send较小的,如果send相同,则选择back较小的
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int INF = 1000000000;
const int maxn = 501;
const int maxc = 100;
int G[maxn][maxn];
int bikes[maxn];
bool vis[maxn] = {0};
vector<int> pre[maxn];
int d[maxn];
int c, n, s, m, perfect;
void dijkstra() {
fill(d, d+maxn, INF);
d[0] = 0;
for (int i = 0; i <= n; ++i)
{
int u = -1;
int MIN = INF;
for (int j = 0; j <= n; ++j)
{
if(MIN > d[j] && !vis[j]) {
u = j;
MIN = d[j];
}
}
if(u == -1) return; // the graph is not connected!
vis[u] = true;
for (int v = 0; v <= n; ++v)
{
if(G[u][v] != INF && !vis[v]) {
//printf("d[%d]:%d ,d[%d]:%d + G[%d][%d]:%d\n", v, d[v], u, d[u], u, v, G[u][v]);
if(d[v] > d[u]+G[u][v]) {
d[v] = d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[v] == d[u]+G[u][v]) {
pre[v].push_back(u);
}
}
}
}
}
vector<int> temp;
int optVal = INF;
int returnBike = 0;
vector<int> bestPath;
void dfs(int s) {
if(s == 0) {
int move = 0;
int remain = 0;
for (int i = temp.size()-1; i >= 0; --i)
{
if(temp[i] > 50) {
remain += bikes[temp[i]] - perfect;
}
else {
if(remain >= perfect - bikes[temp[i]]) {
remain -= (perfect - bikes[temp[i]]);
}
else {
move += perfect - bikes[temp[i]] - remain;
remain = 0;
}
}
}
if(move < optVal) {
optVal = move;
returnBike = remain;
temp.push_back(0);
bestPath = temp;
temp.pop_back();
}
else if(move == optVal) {
if(returnBike > remain) {
optVal = move;
returnBike = remain;
temp.push_back(0);
bestPath = temp;
temp.pop_back();
}
}
//temp.pop_back();
return;
}
temp.push_back(s);
for (int i = 0; i < pre[s].size(); ++i)
{
dfs(pre[s][i]);
}
temp.pop_back();
}
int main() {
scanf("%d %d %d %d", &c, &n, &s, &m);
perfect = c / 2;
fill(G[0], G[0]+maxn*maxn, INF);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &bikes[i]);
}
for (int i = 0; i < m; ++i)
{
int start, end, edge;
scanf("%d %d %d", &start, &end, &edge);
G[start][end] = edge;
G[end][start] = edge;
}
dijkstra();
dfs(s);
printf("%d ", optVal>0?optVal:0);
for (int i = bestPath.size()-1; i >= 0; --i)
{
printf("%d", bestPath[i]);
if(i != 0) printf("->");
}
printf(" %d\n", returnBike);
}
网友评论