1018. Public Bike Management (27分)——深搜

#include<iostream>
#include<stdio.h>
#include<stack>
using namespace std;

const int maxn=505;
const int bignum=999999;
int C,N,S,M;
class node
{
public:
	int to,next,cost;
};
node edge[maxn*3];
int head[maxn],cnt=0,vis[maxn],dis[maxn];
int bike[maxn];
int ans_pre[maxn],pre[maxn],ans_take=bignum,take_back=0;
void Init()
{
	int i,u,v,cost;
	scanf("%d%d%d%d",&C,&N,&S,&M);
	for(i=1;i<=N;i++) scanf("%d",&bike[i]);
	for(i=0;i<M;i++){
		scanf("%d%d%d",&u,&v,&cost);
		edge[++cnt].to =v;
		edge[cnt].next =head[u];
		edge[cnt].cost =cost;
		head[u]=cnt;

		edge[++cnt].to =u;
		edge[cnt].next =head[v];
		edge[cnt].cost =cost;
		head[v]=cnt;
	}
}
void dfs(int u,int bike_in_car,int take_bike) //传入车上有的车辆数  目前需要带的车
{
	int i,v,j;
	for(i=head[u];i;i=edge[i].next ){
		v=edge[i].to ;
		if(!vis[v]) {
			pre[v]=u;
			int now_cost=dis[u]+edge[i].cost ;
			int bike_in_car2=bike_in_car,take_bike2=take_bike;

			if(bike[v]>=C/2) {       /* ----------------------下面这段 更新bike_in_car2、take_bike2 -----*/
				bike_in_car2+=( bike[v]-C/2);
			}
			else {
				if(bike_in_car2>=(C/2-bike[v]))
					bike_in_car2-=(C/2-bike[v]);
				else {
					 take_bike2 +=(C/2-bike[v]-bike_in_car2); bike_in_car2=0;
				}
			}

			if(now_cost<dis[v]){   // 更新dis[v] 
				dis[v]= now_cost;
				if(v==S) {
					ans_take=take_bike2;
					take_back=bike_in_car2;
					j=S;
					while(pre[j]!=-1){
						ans_pre[j]=pre[j];j=pre[j];
					}
					ans_pre[j]=-1;
					continue;
				}
				vis[v]=1;
				dfs(v,bike_in_car2,take_bike2);
				vis[v]=0;
			}
			else if(now_cost==dis[v]) {
				if(v==S){
					if(take_bike2<ans_take) { //路径距离相等 如果需要带的车比较少 则更新
						ans_take=take_bike2;
						take_back=bike_in_car2;
						j=S;
						while(pre[j]!=-1)	{
							ans_pre[j]=pre[j];
							j=pre[j];
						}
						ans_pre[j]=-1;
					}
					continue;
				}
				vis[v]=1;
				dfs(v,bike_in_car2,take_bike2);
				vis[v]=0;
			}
		}	
	}
}
void solve()
{
	int i;
	for(i=0;i<=N;i++) {
		pre[i]=0;vis[i]=0;
		dis[i]=bignum;
	}
	vis[0]=1;pre[0]=-1;ans_pre[0]=-1;dis[0]=0;
	dfs(0,0,0);
	printf("%d ",ans_take);
	stack<int > sta;
	i=S;
	sta.push (S);
	while(pre[i]!=-1) {
		sta.push (ans_pre[i]);
		i=ans_pre[i];
	}
//	sta.push (0);
	printf("%d",sta.top ());
	sta.pop ();
	while(!sta.empty ()){
		printf("->%d",sta.top ());
		sta.pop ();
	}
	printf(" %d\n",take_back);
}
int main()
{
	Init();
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值