题目:https://www.nowcoder.com/pat/5/problem/4324
题意:
车辆管理系统。有一个中心PBMC,N个站点,M条边,站点最大容量C,每个站点有当前停车的数,如果停车数=S/2,则说明此站点perfect。不是perfect都是有问题的点,现在要选一条给指定问题站点解决问题,求最优解(从PBMC到站点耗时最短,当耗时最短,选中心寄出或回收车辆最少的点路径)
第一行,给出 站点最大容量C,站点的个数N,指定问题站点下标,有M条边。
第二行,N个站点停车数
第三行至最后,M条边
分析:
1、求最短路,单源最短路SPFA,求出最短的路径
2、用DFS对比路径,选出最短的路径中,选中心寄出或回收车辆最少的点路径
输入例子:
10 3 3 5 6 7 0 0 1 1 0 2 1 0 3 3 1 3 1 2 3 1
输出例子:
3 0->2->3 0
代码:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn = 501;
const int INF = 1000000000;
struct node
{
int v,l;
node(int _v,int _l):v(_v),l(_l){}
};
vector<node> adj[maxn];
int bike[maxn];
int c,n,s,m;
vector<int> pre[maxn];
int d[maxn];
int inq[maxn];
vector<int> tempPath,path;
int sent = INF,take = INF;
void SPFA()
{
queue<int> q;
for(int i=1;i<=n;i++)
{
d[i]=INF;
}
d[0]=0;
q.push(0);
inq[0]=1;
while(!q.empty())
{
int u = q.front();
q.pop();
inq[u]=0;
for(int i=0;i<adj[u].size();i++)
{
int v=adj[u][i].v;
int l=adj[u][i].l;
if(v == 0)
continue;
if(d[u]+l<d[v])
{
d[v]=d[u]+l;
pre[v].clear();
pre[v].push_back(u);
if(!inq[v])
{
q.push(v);
inq[v]=1;
}
}
else if(d[u]+l==d[v])
pre[v].push_back(u);
}
}
}
void DFS(int x)
{
if(x==0)
{
int remain=0,tempSent=0;
tempPath.push_back(x);
for(int i=tempPath.size()-2;i>=0;i--)
{
int u=tempPath[i];
remain = remain+bike[u]-c/2;
if(remain<0)
{
tempSent+=-remain;
remain=0;
}
}
if(tempSent<sent)
{
path=tempPath;
sent=tempSent;
take=remain;
}
else if(tempSent==sent && remain < take)
{
path=tempPath;
take=remain;
}
tempPath.pop_back();
}
tempPath.push_back(x);
for(int i=0;i<pre[x].size();i++)
{
DFS(pre[x][i]);
}
tempPath.pop_back();
}
int main()
{
int s1,s2,t;
scanf("%d%d%d%d",&c,&n,&s,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&bike[i]);
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&s1,&s2,&t);
node x = node(s2,t);
node y = node(s1,t);
adj[s1].push_back(x);
adj[s2].push_back(y);
}
SPFA();
DFS(s);
printf("%d ",sent);
for(int i= path.size()-1;i>=0;i--)
{
if(i<path.size()-1)
printf("->");
printf("%d",path[i]);
}
printf(" %d",take);
return 0;
}