PAT甲级1018 Public Bike Management

1018 Public Bike Management (30分)

思路:DFS遍历求出所有可能的最短路径,对于每条可能的最短路径求其send和take_back,比较选择最优的;
注意点:不可以从后经过的城市中取自行车给前面的城市;

看别的博客说可以用Dijkstra算法修改一下做DFS,我jio着效率可能会高点,等有时间了我去研究研究!

#include<bits/stdc++.h>
using namespace std;

struct way{
	int send=INT_MAX,takeback=INT_MAX;
	vector<int> path;
};

vector<vector<int>> res;
int mintime=INT_MAX;
void dfs(vector<vector<int>> &roads,int target,vector<int> &tmp,int time,vector<int> &visited){
	if (tmp[tmp.size()-1]==target){
		if(time<mintime){
			res.erase(res.begin(),res.end());
			res.push_back(tmp);
			mintime=time;
		}
		else if(time==mintime){
			res.push_back(tmp);
		}
		return;
	}
	for(int i=1;i<roads.size();i++){
		if(roads[tmp[tmp.size()-1]][i]==0 || visited[i]==1)continue;
		tmp.push_back(i);
		visited[i]=1;
		time+=roads[tmp[tmp.size()-2]][i];
		dfs(roads,target,tmp,time,visited);
		time-=roads[tmp[tmp.size()-2]][i];
		visited[i]=0;
		tmp.pop_back();
	}
}

way ans;
void cnt(vector<vector<int>> res,vector<int> bikes,int c){
	for(int i=0;i<res.size();i++){
		int send=0,tb=0;
		for(int j=1;j<res[i].size();j++){
			if(bikes[res[i][j]]>c)tb+=(bikes[res[i][j]]-c);
			else{
				if(tb>(c-bikes[res[i][j]]))tb-=(c-bikes[res[i][j]]);
				else {
					send+=(c-bikes[res[i][j]]-tb);
					tb=0;
				}
			}
		}
		if(send<ans.send){
			ans.path=res[i];
			ans.send=send;
			ans.takeback=tb;
		}
		else if(send==ans.send && tb<ans.takeback){
			ans.path=res[i];
			ans.send=send;
			ans.takeback=tb;
		}
	}
}

int main(){
	int c,n,t,m;
	cin>>c>>n>>t>>m;
	vector<int> bikes(n+1,0);
	for(int i=0;i<n;i++)cin>>bikes[i+1];
	vector<vector<int>> roads(n+1,vector<int>(n+1,0));
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		cin>>roads[x][y];
		roads[y][x]=roads[x][y];
	}
	vector<int> tmp(1,0);
	vector<int> visited(n+1,0);
	visited[0]=1;
	int time=0;
	dfs(roads,t,tmp,time,visited);
	cnt(res,bikes,c/2);
	
	cout<<ans.send<<" ";
	for(int i=0;i<ans.path.size();i++){
		cout<<ans.path[i];
		if(i<ans.path.size()-1)cout<<"->";
		else cout<<" ";
	}
	cout<<ans.takeback;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值