PAT.A1018公共自転車管理

目次に戻るここに画像の説明を挿入

ここに画像の説明を挿入

タイトル

市内には公共の自転車ステーションがいくつかありますが、各ステーションの最大自転車容量は偶数Cmaxであり、ステーション内の自転車の数がちょうどCmax / 2である場合、そのステーションは「完全な状態」にあると言えます。ステーションの容量が満杯または空の場合、コントロールセンター(PBMC)が一定数の自転車を道路からステーションに運ぶか収集するため、問題のあるステーションと途中のすべてのステーションが「完全な状態」になります。次に、Cmax、ステーション数N(コントロールセンターPBMCを除く)、問題のステーション数Sp、無向エッジの数M、エッジの重みを指定し、PBMC(0とマークされている)から問題のステーションSpへの最短経路、出力の必要性を求めます。 PBMCから輸送された自転車の数、最短経路、および問題の駅に到着した後に戻す必要のある自転車の数。複数の最短経路がある場合は、PBMCから自転車が最も少ない経路を選択します。それでも複数がある場合は、問題のステーションから返された自転車が最も少ない経路を選択します。注:途中のすべてのステーションの調整プロセスは、問題のあるステーションへの移動中に完了する必要があり、戻されたときに調整は行われません。

サンプル(コピー可能)

10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1
//output
3 0->2->3 0

注意点

  1. この問題の解決策は、Djikstra + DFSです。具体的には、最初にダイクストラを使用して最短経路を見つけ、その過程で各パスの各ノードの前駆ノードを記録します。DFSを使用して問題のあるサイトから開始し、記録した先駆ノードを使用してPBMCに戻り、パスを記録してから、PBMCから開始して、持参する必要がある自転車の数と取得する必要がある自転車の数を計算します。最短経路を更新します。
#include<bits/stdc++.h>
using namespace std;

int Cmax,n,sp,m,minneed=INT_MAX,minremain=INT_MAX;//Cmax为最大容量,n为顶点数,sp为问题站点,m为边数
int G[510][510],weight[510],dis[510];//G为图,weight为车站单车数量,dis为到某节点的距离
bool vis[510]={false};//标记是否访问过该节点
vector<int> temp,path,pre[510];//temp为临时路径,path为最短路径,pre存储前驱节点
void Dijkstra(){
	fill(dis,dis+n+1,INT_MAX); //注意第二个参数为dis+n+1
	dis[0]=0;
	while(!vis[sp]){
		int v,minn=INT_MAX;
		for(int i=0;i<=n;i++){
			if(!vis[i]&&dis[i]<minn){
				minn=dis[i];
				v=i;
			}
		}	
		vis[v]=true;
		for(int i=0;i<=n;i++){
			if(!vis[i]&&G[v][i]!=0&&dis[i]>dis[v]+G[v][i]){
				dis[i]=dis[v]+G[v][i];
				pre[i].clear();
				pre[i].push_back(v);
			}else if(!vis[i]&&G[v][i]!=0&&dis[i]==dis[v]+G[v][i]){
				pre[i].push_back(v);
			}
		}
	}
}
void DFS(int v){
    temp.push_back(v);
	if(v==0){
		int need=0,remain=0;
		for(int i=temp.size()-1;i>=0;i--){//注意从后往前才是从PBMC出发到问题站点的路径
			int now=temp[i];
			if(weight[now]>=0){
				remain+=weight[now];
			}else{
				if(remain>abs(weight[now])){
					remain+=weight[now];
				}else{
					need+=abs(weight[now])-remain;
					remain=0;
				}
			}
		}
		if(need<minneed){
			path=temp;
			minneed=need;
			minremain=remain;
		}else if(need==minneed&&remain<minremain){
			path=temp;
			minneed=need;
			minremain=remain;
		}
		temp.pop_back();
		return;
	}
	for(int i=0;i<pre[v].size();i++)DFS(pre[v][i]);
	temp.pop_back();
}
int main(){
	cin>>Cmax>>n>>sp>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&weight[i]);
		weight[i]-=Cmax/2; 
	} 
	int u,v,w;
	while(m--){
		scanf("%d%d%d",&u,&v,&w);
		G[u][v]=G[v][u]=w;
	}
	Dijkstra();
	DFS(sp);
	printf("%d ",minneed);
	for(int i=path.size()-1;i>=0;i--){
		printf("%d",path[i]);
		if(i>0)printf("->");
	}
	printf(" %d",minremain);
    return 0;
}
元の記事を177件公開 賞賛5 訪問数6652

おすすめ

転載: blog.csdn.net/a1920993165/article/details/105567424