タイトル説明
杭州市には、世界中からの観光客に大きな利便性を提供する公共自転車サービスがあります。どの駅でも自転車を借りて、市内の他の駅に返却することができます。
パブリックバイク管理センター(PBMC)は、すべてのステーションの容量をリアルタイムで監視し続けます。ステーションがちょうど半分満たされている場合、ステーションは完全な状態にあると言われます。ステーションが満員または空の場合、PBMCは自転車を収集または送信して、そのステーションの状態を完全に調整します。さらに、途中のすべてのステーションも調整されます。
問題のあるステーションが報告されると、PBMCは常にそのステーションに到達するための最短パスを選択します。最短経路が複数ある場合は、PBMCから送信される自転車の数が最も少ない経路が選択されます。
図1に例を示します。ステーションは頂点で表され、道路はエッジに対応します。エッジの数字は、あるエンドステーションから別のエンドステーションに到達するのにかかる時間です。頂点Sの内側に書かれている数は、Sに格納されている現在の自転車の数です。各ステーションの最大容量が10であるとすると、S3の問題を解決するために、2つの異なる最短経路があります。
- PBMC-> S1-> S3。この場合、S1から1台の自転車を収集し、S3に5台の自転車を運ぶことができるため、PBMCから4台の自転車を送信する必要があります。これにより、両方のステーションが完全な状態になります。
- PBMC-> S2-> S3。このパスにはパス1と同じ時間が必要ですが、PBMCから送信される自転車は3台のみであるため、選択されます。
説明を入力してください
各入力ファイルには、1つのテストケースが含まれています。いずれの場合も、最初の行には4つの数値が含まれています。Cmax(<= 100)は常に偶数であり、各ステーションの最大容量です。N(<= 500)、ステーションの総数。Sp、問題のあるステーションのインデックス(ステーションには1からNまでの番号が付けられ、PBMCは頂点0で表されます)。M、道路の数。2行目には、N個の非負の数Ci(i = 1、…N)が含まれています。ここで、各Ciは、それぞれSiでの現在の自転車の数です。次にM行が続き、それぞれにSi、Sj、Tijの3つの数字が含まれ、TijがステーションSiとSjの間を移動するのにかかった時間を表します。行内のすべての数字はスペースで区切られます。
出力の説明
テストケースごとに、結果を1行で印刷します。まず、PBMCが送信する必要のある自転車の数を出力します。次に、1スペース後に、パスを0-> S1->…-> Spの形式で出力します。最後に、別のスペースの後に、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
出力例
3 0-> 2-> 3 0
回答
#include<bits/stdc++.h>
using namespace std;
const int inf=0x7ffffff;
int M[510][510],c,n,m,x,v[510],ansx,ansy,anscost,anssent;
vector<int>ans,temp;
void dfs(int cur,int cost,int sent,int back){
temp.push_back(cur);
if(cur==x){
if(cost<anscost||(cost==anscost&&sent<anssent)){
anscost=cost;
anssent=sent;
ans=temp;
ansx=sent;
ansy=back;
}
return;
}
for(int i=1;i<=n;i++){
if(M[cur][i]!=-1&&!v[i]){
v[i]=1;
if(M[i][i]<c/2){
if(back+M[i][i]>=c/2) dfs(i,cost+M[cur][i],sent,back-(c/2-M[i][i]));
else dfs(i,cost+M[cur][i],sent+c/2-back-M[i][i],0);
}
else dfs(i,cost+M[cur][i],sent,back+M[i][i]-c/2);
temp.pop_back();
v[i]=0;
}
}
}
int main()
{
while(~scanf("%d %d %d %d",&c,&n,&x,&m)){
for(int i=1;i<=n;i++) scanf("%d",&M[i][i]);
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
if(i!=j) M[i][j]=-1;
}
}
for(int i=0;i<m;i++){
int x,y,z;scanf("%d %d %d",&x,&y,&z);
M[x][y]=z;M[y][x]=z;
}
ans.clear();
temp.clear();
memset(v,0,sizeof(v));
anscost=inf;anssent=inf;
dfs(0,0,0,0);
printf("%d ",ansx);
for(int i=0;i<ans.size()-1;i++) printf("%d->",ans[i]);
printf("%d ",ans[ans.size()-1]);
printf("%d\n",ansy);
}
}