这道题网上大部分都是用单元最短路径做的,我一开始想到的方法是dfs,因为这种思路就是跟着题目中的逻辑来实现的
然后其中有一个坑,坑住我了,就是
判断级别的时候,直接在一开始进行判断,我一开始wr了好多了,就是因为在当前节点的某个分支处才判断,其实在一开始就要判断,因为如果等级差超过了给定的m,也不能用直接获取当前节点不打折的价钱的方法进行购买
下面是代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int m,n;
int price[110];
int level[110];
int num[110][110];
int answer;
int alter[110];
int disCount[110][110];
int vis[110];
void slove(int cnt,int sum,int MinL,int MaxL)
{
int x=MinL;
int y=MaxL;
if(y-x>m)return;
int l=alter[cnt];
if(l==0)
{
sum+=price[cnt];
if(answer>sum)
answer=sum;
}
else
{
if(sum+price[cnt]<answer)
answer=sum+price[cnt];
for(int j=1; j<=l; ++j)
{
int nu_m=num[cnt][j];
int dis_c=disCount[cnt][j];
int lev_el=level[nu_m];
if(answer>sum&&(!vis[nu_m]))
{
MinL=min(x,lev_el);
MaxL=max(y,lev_el);
vis[nu_m]=1;
slove(nu_m,sum+dis_c,MinL,MaxL);
vis[nu_m]=0;
}
}
}
}
int main()
{
while(cin>>m>>n)
{
int a,b,c;
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; ++i)
{
cin>>a>>b>>c;
price[i]=a;
level[i]=b;
alter[i]=c;
for(int j=1; j<=c; ++j)
{
cin>>num[i][j];
cin>>disCount[i][j];
}
}
answer=price[1];
vis[1]=1;
slove(1,0,level[1],level[1]);
cout<<answer<<endl;
}
}