【PAT】A1018 Public Bike Management

Dijkstra+DFS解决,难点在handle函数计算路径的Need 和Remain

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=510;
const int INF=0x3fffffff;
int G[MAXN][MAXN];
int vis[MAXN]={false};
int d[MAXN];
int weight[MAXN];
vector<int> pre[MAXN];
vector<int> path,tempPath;
int C,N,S,M;
void Dijkstra(int s){
	fill(d,d+MAXN,INF);
	d[s]=0;
	for(int i=0;i<=N;i++){
		int MIN=INF,u=-1;
		for(int j=0;j<=N;j++){
			if(vis[j]==false&&d[j]<MIN){
				MIN=d[j];
				u=j;
			}
		} 
		if(u==-1)return ;
		vis[u]=true;
		for(int v=0;v<=N;v++){
			if(G[u][v]!=INF&&vis[v]==false){
				if(d[u]+G[u][v]<d[v]){
					d[v]=d[u]+G[u][v];
					pre[v].clear();
					pre[v].push_back(u);
				}else if(d[u]+G[u][v]==d[v]){
					pre[v].push_back(u);
				}
			}
		}
	}
}
void handle(vector<int>path,int& need,int &remain){
	for(int i=path.size()-2;i>=0;i--){
		int id=path[i];
		if(weight[id]>0){
			remain+=weight[id];
		}else {
			if(remain>abs(weight[id])){
				remain-=abs(weight[id]);
			}else{
				need+=abs(weight[id])-remain;
				remain=0;
			}
		}
	}
}
int needMIN=INF,remainMIN=INF;
void DFS(int v){
	if(v==0){
		tempPath.push_back(v);
		int need=0,remain=0;
		handle(tempPath,need,remain);
		if(need<needMIN){
			needMIN=need;
			remainMIN=remain;
			path=tempPath;
		}else if(need==needMIN&&remain<remainMIN){
			remainMIN=remain;
			path=tempPath;
		}		
		tempPath.pop_back();
		return;
	}
	tempPath.push_back(v);
	for(int i=0;i<pre[v].size();i++){
		DFS(pre[v][i]);
	}
	tempPath.pop_back();
}
int main(){
	fill(G[0],G[0]+MAXN*MAXN,INF);
	scanf("%d%d%d%d",&C,&N,&S,&M);
	for(int i=1;i<=N;i++){
		int w;
		scanf("%d",&w);
		weight[i]=w-C/2;
	}
	for(int i=0;i<M;i++){
		int u,v,dis;
		scanf("%d%d%d",&u,&v,&dis);
		G[u][v]=G[v][u]=dis;
	}
	Dijkstra(0);
	DFS(S);
	printf("%d ",needMIN);
	for(int i=path.size()-1;i>=0;i--){
		printf("%d",path[i]);
		if(i>0)printf("->");
	}
	printf(" %d\n",remainMIN);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值