Public Bike Management

本文深入探讨了SPFA(Shortest Path Faster Algorithm)算法在寻找图中节点间最短路径的应用。通过具体实例,展示了如何利用SPFA算法进行节点间的路径寻优,同时考虑了边的权重和节点的特性,最终实现了从源节点到目标节点的最短路径计算,并通过代码实现了解决方案。
摘要由CSDN通过智能技术生成
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int last[505],cnt,t,val[505],cm,m,n,a,b,c,d[505],rd[505],inq[505],front[505],maxn=0x3f3f3f3f,num1=0x3f3f3f3f,pro[505];
struct edge
{
	int v,w,next;
}e[500005];
edge ze[500005];
inline void insert(int u,int v,int w)
{
	cnt++;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].next=last[u];
	last[u]=cnt;
}
inline void add(int u,int v)
{
	cnt++;
	ze[cnt].v=v;
	ze[cnt].next=front[u];
	front[u]=cnt;
}
void spfa(int di[],int s){
	queue<int>q; 
	for(int i=0;i<=n;i++)
	di[i]=0x3f3f3f3f;
	di[s]=0;inq[s]=1;q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();inq[u]=0;
		for(int i=last[u];i;i=e[i].next)
		{
			int v=e[i].v;
			if(di[v]>di[u]+e[i].w){
				di[v]=di[u]+e[i].w;
				if(!inq[v]){
					inq[v]=1;q.push(v);
				}
			}
		}
	}
}
bool dfs(int u,int num,int ans)
{
	bool f=0;
    int tmp1=ans,tmp2=num;
	if(u==t)
	{
		if(maxn==ans&&num1>num)
		{
			num1=num;
			return 1;
		}
		if(maxn>ans)
		{
			num1=num;
		    maxn=min(maxn,ans);
		    return 1;
		}
		return 0;
	}
	for(int i=front[u];i;i=ze[i].next)
	{
		int v=ze[i].v;
		num+=val[v];
		if(num<0)
		{
			ans-=num;
			num=0;
		}
		bool j=dfs(v,num,ans);
		if(j) pro[v]=u,f=1;
		ans=tmp1;
		num=tmp2;
	}
	return f;
}
void outt(int u)
{
	if(!u)
	{
		cout<<u<<"->";
		return;
	}
	outt(pro[u]);
	if(u!=t)
	cout<<u<<"->";
	else
	cout<<u;
}
int main()
{
	cin>>cm>>n>>t>>m;
	cm/=2;
	for(int i=1;i<=n;i++)
	cin>>val[i],val[i]-=cm;
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b>>c;
		insert(a,b,c);
		insert(b,a,c);
	}
	spfa(d,0);
	memset(inq,0,sizeof(inq));
	spfa(rd,t);
	cnt=0;
	for(int i=0;i<=n;i++)
	{
		for(int j=last[i];j;j=e[j].next)
		{
			if(d[i]+e[j].w+rd[e[j].v]==d[t])
			add(i,e[j].v);
		}
	}
	dfs(0,0,0);
	cout<<maxn<<' ';
	outt(t);
	cout<<' '<<num1;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈希表扁豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值