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

1018. Public Bike Management (30)

1018 Public Bike Management (30 分)

1018 Public Bike Management (30分)

PAT A1018.Public Bike Management

1018 Public Bike Management (30)(30 分)