PAT A 1018.Public Bike Management (30)

题目

There is a public bike service in Hangzhou City which provides greatconvenience to the tourists from all over the world. One may rent a bike at anystation and return it to any other stations in the city.

The Public Bike Management Center (PBMC) keeps monitoring the real-timecapacity of all the stations. A station is said to be inperfectcondition if it is exactly half-full. If a station is full or empty, PBMC willcollect or send bikes to adjust the condition of that station to perfect. Andmore, all the stations on the way will be adjusted as well.

When a problem station is reported, PBMC will always choose the shortestpath to reach that station. If there are more than one shortest path, the onethat requires the least number of bikes sent from PBMC will be chosen.


Figure 1

Figure 1 illustrates an example. The stations are represented by verticesand the roads correspond to the edges. The number on an edge is the time takento reach one end station from another. The number written inside a vertex S isthe current number of bikes stored at S. Given that the maximum capacity ofeach station is 10. To solve the problem at S3, we have 2 differentshortest paths:

1. PBMC -> S1 -> S3. In this case, 4 bikesmust be sent from PBMC, because we can collect 1 bike from S1 andthen take 5 bikes to S3, so that both stations will be in perfectconditions.

2. PBMC -> S2 -> S3. This path requires thesame time as path 1, but only 3 bikes sent from PBMC and hence is the one thatwill be chosen.

Input Specification:

Each input file contains one test case. For each case, the first linecontains 4 numbers: Cmax (<= 100), always an even number, is themaximum capacity of each station; N (<= 500), the total number of stations;Sp, the index of the problem station (the stations are numbered from1 to N, and PBMC is represented by the vertex 0); and M, the number of roads.The second line contains N non-negative numbers Ci (i=1,...N) whereeach Ci is the current number of bikes at Sirespectively. Then M lines follow, each contains 3 numbers: Si, Sj,and Tij which describe the time Tij taken to move betwenstations Si and Sj. All the numbers in a line areseparated by a space.

Output Specification:

For each test case, print your results in one line. First output thenumber of bikes that PBMC must send. Then after one space, output the path inthe format: 0->S1->...->Sp. Finally afteranother space, output the number of bikes that we must take back to PBMC afterthe condition of Sp is adjusted to perfect.

Note that if such a path is not unique, output the one that requiresminimum number of bikes that we must take back to PBMC. The judge's dataguarantee that such a path is unique.

Sample Input:

10 3 3 5

6 7 0

0 1 1

0 2 1

0 3 3

1 3 1

2 3 1

Sample Output:

3 0->2->3 0

 

题目很长,但是不难

1、以请求点为目的地求个点距离

2、从中心开始,dfs求路线,求路线的过程中的处理

(1)累加每点的车和目标数的差值;

(2)记录累加过程中出现的绝对值最大的负数(这个绝对值即需要从中心运出的车数);

(3)每次到达请求的点则刷新取绝对值小的那个,相同时取(1)中累加差小的那个(可以少运车回中心)

3、保留的那个负数的绝对值即中心运出的车,累加差减那个负数就是运回的车

 

代码:

B-F较慢

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

const int MAX=0x0fffffff;

struct way	//路线探测结构
{
	int station;	//到达的station
	vector<int> road;	//路线记录
	int larg_neg;	//最大的负数(即为需要从中心调出的自行车数量)
	int bike;	//到达station时的自行车数
};

void Print_data(way sp_w);	//按要求打印数据

int main()
{
	int cmax,n,sp,m;	//规定输入
	int map[501][501];	//地图
	int bike[501];	//自行车记录,bike[0]无意义,从1~500
	int length[501];	//距离(到目的地)

	int i,j,s1,s2,l;
	for(i=0;i<501;i++)	//初始化
	{
		length[i]=MAX;
		for(j=0;j<501;j++)
			map[i][j]=MAX;
	}

	cin>>cmax>>n>>sp>>m;

	bike[0]=0;	//输入信息
	for(i=0;i<n;i++)
		cin>>bike[i+1];
	for(i=0;i<m;i++)
	{
		cin>>s1>>s2>>l;
		if(l<map[s1][s2])
		{
			map[s1][s2]=l;
			map[s2][s1]=l;
		}
	}

	length[sp]=0;	//B-F算法,较慢
	for(int k=0;k<=n;k++)
		for(i=0;i<=n;i++)
			for(j=0;j<=n;j++)
				if(i!=j&&map[i][j]+length[i]<length[j])
					length[j]=map[i][j]+length[i];

	way sp_w;	//表示终点
	sp_w.bike=-MAX;
	sp_w.larg_neg=-MAX;
	way temp_w1,temp_w2;
	stack<way> way_test;	//路径探测堆栈
	temp_w1.station=0;		//初始化,压入中心(station 0)
	temp_w1.road.push_back(0);
	temp_w1.bike=0;
	temp_w1.larg_neg=0;
	way_test.push(temp_w1);
	while(!way_test.empty())	//深度优先探测路线
	{
		temp_w1=way_test.top();
		way_test.pop();
		if(temp_w1.station!=sp)
		{
			for(i=1;i<=n;i++)
			{
				if(temp_w1.station!=i&&
					map[temp_w1.station][i]<MAX&&
					length[i]+map[temp_w1.station][i]==length[temp_w1.station])
				{
					temp_w2.station=i;
					temp_w2.road=temp_w1.road;
					temp_w2.road.push_back(i);
					temp_w2.bike=temp_w1.bike+bike[i]-cmax/2;
					if(temp_w2.bike<temp_w1.larg_neg)	//刷新最大负数
						temp_w2.larg_neg=temp_w2.bike;
					else
						temp_w2.larg_neg=temp_w1.larg_neg;
					way_test.push(temp_w2);
				}
			}
		}
		else	//到达目的地时,进行比较,保留当前最优路线
		{
			if(temp_w1.larg_neg>sp_w.larg_neg)
				sp_w=temp_w1;
			else if(temp_w1.larg_neg==sp_w.larg_neg&&
				temp_w1.bike<sp_w.bike)
				sp_w=temp_w1;
		}
	}
	Print_data(sp_w);

	return 0;
}

void Print_data(way sp)	//按要求输出
{
	int i;
	cout<<-sp.larg_neg<<" ";
	cout<<0;
	for(i=1;i<sp.road.size();i++)
		cout<<"->"<<sp.road[i];
	cout<<" "<<sp.bike-sp.larg_neg;
}


代码:

dijkstra

#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;

const int MAX=0x0fffffff;

struct way	//路线探测结构
{
	int station;	//到达的station
	vector<int> road;	//路线记录
	int larg_neg;	//最大的负数(即为需要从中心调出的自行车数量)
	int bike;	//到达station时的自行车数
};

void Print_data(way sp_w);	//按要求打印数据

int main()
{
	int cmax,n,sp,m;	//规定输入
	int map[501][501];	//地图,中心为0
	int bike[501];	//自行车记录,bike[0]无意义,从1~500
	int length[501];	//距离(到目的地)

	int i,j,s1,s2,l;
	for(i=0;i<501;i++)	//初始化
	{
		length[i]=MAX;
		for(j=0;j<501;j++)
			map[i][j]=MAX;
	}

	cin>>cmax>>n>>sp>>m;

	bike[0]=0;	//输入信息
	for(i=0;i<n;i++)
		cin>>bike[i+1];
	for(i=0;i<m;i++)
	{
		cin>>s1>>s2>>l;
		if(l<map[s1][s2])
		{
			map[s1][s2]=l;
			map[s2][s1]=l;
		}
	}

	int flag[501]={0};	//标记点是否已经用于松弛
	int min=sp;		//本轮松弛点
	int tmin=0,tdis=0;	//扫描下一轮用的松弛点
	length[sp]=0;
	flag[sp]=1;
	while(tdis!=MAX+1)	//dijkstra
	{
		tdis=MAX+1;
		for(i=0;i<=n;i++)
		{
			if(i!=min&&map[min][i]+length[min]<length[i])
				length[i]=map[min][i]+length[min];
			if(flag[i]==0&&length[i]<tdis)
			{
				tmin=i;
				tdis=length[i];
			}
		}
		min=tmin;
		flag[min]=1;
	}

	way sp_w;	//表示终点
	sp_w.bike=-MAX;
	sp_w.larg_neg=-MAX;
	way temp_w1,temp_w2;
	stack<way> way_test;	//路径探测堆栈
	temp_w1.station=0;		//初始化,压入中心(station 0)
	temp_w1.road.push_back(0);
	temp_w1.bike=0;
	temp_w1.larg_neg=0;
	way_test.push(temp_w1);
	while(!way_test.empty())	//深度优先探测路线
	{
		temp_w1=way_test.top();
		way_test.pop();
		if(temp_w1.station!=sp)
		{
			for(i=1;i<=n;i++)
			{
				if(temp_w1.station!=i&&
					map[temp_w1.station][i]<MAX&&
					length[i]+map[temp_w1.station][i]==length[temp_w1.station])
				{
					temp_w2.station=i;
					temp_w2.road=temp_w1.road;
					temp_w2.road.push_back(i);
					temp_w2.bike=temp_w1.bike+bike[i]-cmax/2;
					if(temp_w2.bike<temp_w1.larg_neg)	//刷新最大负数
						temp_w2.larg_neg=temp_w2.bike;
					else
						temp_w2.larg_neg=temp_w1.larg_neg;
					way_test.push(temp_w2);
				}
			}
		}
		else	//到达目的地时,进行比较,保留当前最优路线
		{
			if(temp_w1.larg_neg>sp_w.larg_neg)
				sp_w=temp_w1;
			else if(temp_w1.larg_neg==sp_w.larg_neg&&
				temp_w1.bike<sp_w.bike)
				sp_w=temp_w1;
		}
	}
	Print_data(sp_w);

	return 0;
}

void Print_data(way sp)	//按要求输出
{
	int i;
	cout<<-sp.larg_neg<<" ";
	cout<<0;
	for(i=1;i<sp.road.size();i++)
		cout<<"->"<<sp.road[i];
	cout<<" "<<sp.bike-sp.larg_neg;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值