原题链接:
https://www.patest.cn/contests/pat-a-practise/1018
思路:
DFS,同时得到结果的时候判断是否为最优
注意:
最优性的判断:距离>带出数目>带回数目
CODE:
#include<iostream>
#include<cstring>
#include<string>
#define N 510
using namespace std;
int c,n,p,m;
int dist[N][N];
int cy[N];
int ca=0;
int path[N];
int re[N];
int mind=1000000;
int minb=1000000;
int mino=1000000;
int floor=0;
int ggg=0;
bool fl[N];
void dfs(int now,int dis)
{
//cout<<now<<" "<<car<<" "<<dis<<" "<<floor<<endl;
if (now==p)
{
int sum=0;
int mmm=0;
int sum1=0;
for (int i=1;i<=floor;i++)
{
sum1+=cy[path[i]];
sum+=c-cy[path[i]];
mmm=max(mmm,sum);
}
int mini=max(0,sum1+mmm-floor*c);
//cout<<now<<" "<<car<<" "<<dis<<" "<<floor<<endl;
if (dis<mind)
{
mind=dis;
for (int i=0;i<=floor;i++)
re[i]=path[i];
ggg=floor;
mino=mmm;
minb=mini;
}
else if (dis==mind)
{
if (mmm<mino)
{
mind=dis;
for (int i=0;i<=floor;i++)
re[i]=path[i];
ggg=floor;
mino=mmm;
minb=mini;
}
else if(mmm==mino)
{
if (mini<minb)
{
mind=dis;
for (int i=0;i<=floor;i++)
re[i]=path[i];
ggg=floor;
mino=mmm;
minb=mini;
}
}
}
return;
}
for (int i=1;i<=n;i++)
{
if (fl[i]==1) continue;
if (dist[now][i]==-1) continue;
//cout<<now<<" "<<i<<" "<<car<<" "<<(cy[i]-c)<<endl;
floor++;
fl[i]=1;
path[floor]=i;
dfs(i,dis+dist[now][i]);
floor--;
fl[i]=0;
}
return;
}
int main()
{
memset(dist,-1,sizeof(dist));
memset(fl,0,sizeof(fl));
cin>>c>>n>>p>>m;
c/=2;
for (int i=1;i<=n;i++) cin>>cy[i];
//for (int i=1;i<=n;i++) cout<<cy[i]<<endl;
for (int i=0;i<m;i++)
{
int u,v,co;
cin>>u>>v>>co;
dist[u][v]=co;
dist[v][u]=co;
}
//cout<<endl;
fl[0]=1;
path[0]=0;
dfs(0,0);
cout<<mino<<" ";
for (int i=0;i<ggg;i++)
cout<<re[i]<<"->";
cout<<re[ggg]<<" ";
cout<<minb;
//cout<<max(sum1+mmm-c*ggg,0);
return 0;
}