1018 Public Bike Management (30 分) 难度: 难 / 知识点: 图论 最短路 图的遍历
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1018 Public Bike Management (30 分) 难度: 难 / 知识点: 图论 最短路 图的遍历相关的知识,希望对你有一定的参考价值。
https://pintia.cn/problem-sets/994805342720868352/problems/994805489282433024
需要注意的是,往回拉的车,是不可以补我们去的时候不够的车站的。
例如: 0-1-2,1是4 2是6 最佳状态是5 那么我们需要 补1 拉1
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int maxv,n,m,endx;
int g[N][N],st[N],dist[N],bike[N];
int ans1=1e9,ans2=1e9;//发送 拉回
vector<int>ans,path;
void Dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[0]=0;
for(int i=0;i<n+1;i++)
{
int t=-1;
for(int j=0;j<=n;j++) if(!st[j]&&(t==-1 || dist[j]<dist[t])) t=j;
st[t]=1;
for(int j=0;j<=n;j++) dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
void dfs(int u,int sum1,int sum2)
{
if(u==endx)//到达目的地了
{
if(sum1<ans1) ans1=sum1,ans2=sum2,ans=path;//发送的数量有更小的
else if(sum1==ans1&&sum2<ans2) ans2=sum2,ans=path;//发送的数量相同,回收的有更小的
return;
}
for(int i=1;i<=n;i++)
{
if(dist[i]==dist[u]+g[u][i])//说明是最短路上的点
{
path.push_back(i);
if(sum2+bike[i]>=maxv/2) dfs(i,sum1,sum2+bike[i]-maxv/2);//当前的点加上补的可以达到最优
else dfs(i,sum1+(maxv/2-bike[i]-sum2),0);//当前的点加上补的还少
path.pop_back();
}
}
}
int main(void)
{
cin>>maxv>>n>>endx>>m;
memset(g,0x3f,sizeof g);
for(int i=1;i<=n;i++) cin>>bike[i];
while(m--)
{
int a,b,c; cin>>a>>b>>c;
g[a][b]=g[b][a]=min(g[a][b],c);
}
Dijkstra();//跑一下最短路
path.push_back(0);
dfs(0,0,0);//当前的点,总共发送多少自行车,总共拉回多少辆
cout<<ans1<<" ";
for(int i=0;i<ans.size();i++)
{
if(i) cout<<"->";
cout<<ans[i];
}
if(ans2==1e9) ans2=0;
cout<<" "<<ans2;
return 0;
}
以上是关于1018 Public Bike Management (30 分) 难度: 难 / 知识点: 图论 最短路 图的遍历的主要内容,如果未能解决你的问题,请参考以下文章
1018. Public Bike Management (30)
1018 Public Bike Management (30 分)
1018 Public Bike Management (30分)