题解
原题链接
这题我一开始没读懂题意,其实题目意思是这样的,给你一个需要调整的位置然后你需要找一条从PBMC(0位置点)到给定位置的最短路径,这个最短路径可能有多条
注意点:
- 从PBMC到给定位置,其路径所经过点都需要调整到perfect
- 不能返回的时候再调整,多的自行车可以带回
- 最短路径有多条的时候优先选择从PBMC带出自行车最少的那一条,如果还有多条就选择最终返回所带自行车数目最少的,题目保证这样的路径只有一条
解题思路:
- Dijkstra首先保存所有的最短路径
- dfs一遍,筛选出最优解
AC代码
#include <cstdio>
#include <vector>
#include <algorithm>
#define maxn 510
#define inf 1e9
using namespace std;
void dijkstra();
void dfs(int v);
struct Edge
{
int to;
int cost;
};
int C, N, S, M;
int v[maxn], dist[maxn], cap[maxn], minout=inf, minback=inf;
bool vis[maxn];
vector<Edge> E[maxn];
vector<int> pre[maxn], tempath, path;
int main()
{
fill(dist, dist+maxn, inf);
fill(vis, vis+maxn, false);
scanf("%d %d %d %d",&C, &N, &S, &M);
for (int i=1; i<=N; i++)
{
scanf("%d",&cap[i]);
cap[i] -= C/2;
}
for (int i=1; i<=M; i++)
{
int v1, v2, cost;
Edge e1, e2;
scanf("%d %d %d",&v1, &v2, &cost);
e1.to = v2;
e1.cost = cost;
e2.to = v1;
e2.cost = cost;
E[v1].push_back(e1);
E[v2].push_back(e2);
}
dijkstra();
dfs(S);
printf("%d ",minout);
for (int i=path.size()-1; i>0; i--)
printf("%d->", path[i]);
printf("%d %d",path[0],minback);
printf("\n%d",sizeof vis);
return 0;
}
void dijkstra()
{
for (int i=0; i<E[0].size(); i++)
{
dist[E[0][i].to] = E[0][i].cost;
pre[E[0][i].to].push_back(0);
}
vis[0] = true;
for (int vertex=1; vertex<=N; vertex++)
{
int MIN=inf, u=-1, v, cost;
for(int i=1; i<=N; i++)
{
if (vis[i]==false&&dist[i]<MIN)
{
MIN = dist[i];
u = i;
}
}
if (u==-1)
return;
vis[u] = true;
for (int i=0; i<E[u].size(); i++)
{
v = E[u][i].to;
cost = E[u][i].cost;
if (vis[v] == false)
{
if (dist[u]+cost < dist[v])
{
dist[v] = dist[u]+cost;
pre[v].clear();
pre[v].push_back(u);
}
else if (dist[u]+cost == dist[v])
pre[v].push_back(u);
}
}
}
}
void dfs(int v)
{
tempath.push_back(v);
if (v==0)
{
int nowhave=0, takeout=0;
for (int i=tempath.size()-1; i>=0; i--)
{
if(cap[tempath[i]] >= 0)
nowhave += cap[tempath[i]];
else
{
if (nowhave+cap[tempath[i]] >= 0)
nowhave += cap[tempath[i]];
else
{
takeout -= (nowhave+cap[tempath[i]]);
nowhave = 0;
}
}
}
if (takeout < minout)
{
path = tempath;
minout = takeout;
minback = nowhave;
}
else if (takeout == minout && nowhave < minback)
{
path = tempath;
minback = nowhave;
}
tempath.pop_back();
return;
}
for (int i=0; i<pre[v].size(); i++)
dfs(pre[v][i]);
tempath.pop_back();
}
end