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 分) 难度: 难 / 知识点: 图论 最短路 图的遍历的主要内容,如果未能解决你的问题,请参考以下文章