思路:
依题意,一个物品可以用另一个物品加金币来代替,那么只要知道另一个物品的最低金币数即可,很容易想到记忆化搜索的思路
只需判断一下等级限制,枚举每条边,取最小值即可
#include<iostream> #include<fstream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #include<set> #include<queue> #include<map> #include<utility> #define REP(i,l,r) for(int i=(l);i<=(r);++i) #define REP2(i,l,r) for(int i=(l);i>=(r);--i) #define CLR(a,v) memset(a,v,sizeof(a)) #define sqr(x) ((x)*(x)) #define SCAN(n) scanf("%d",&n) #define SCAN2(n,m) scanf("%d %d",&n,&m) #define SCANS(s) scanf("%s",s) #define PRINT(n) printf("%d\n",n) #define pb push_back #define mp make_pair using namespace std; typedef long long ll; typedef pair<int,int> pii; typedef vector<int> vi; const int INF=1e9; const double eps=1e-8; const int MOD=(int)1e9+7; const int N=100010; /*------------------------------------------------------------------------*/ int first[110],level[110],price[110]; int nex[10010],w[10010],v[10010],u[10010]; int d[110]; /*------------------------------------------------------------------------*/ int search(int x,int maxl,int minl,int m){ if(d[x]>0) return d[x]; d[x]=price[x]; for(int e=first[x];e!=-1;e=nex[e]){ int l=level[v[e]]; if(abs(l-maxl)<=m&&abs(l-minl)<=m){ d[x]=min(d[x],search(v[e],max(maxl,l),min(minl,l),m)+w[e]); } } return d[x]; } int main(){ int n,num,x,y,m; while(SCAN2(m,n)!=EOF){ int cnt=1; CLR(first,-1); CLR(d,0); REP(i,1,n){ scanf("%d %d %d",&price[i],&level[i],&num); REP(j,1,num){ SCAN2(x,y); u[cnt]=i,v[cnt]=x,w[cnt]=y; nex[cnt]=first[i]; first[i]=cnt; cnt++; } } PRINT(search(1,level[1],level[1],m)); } return 0; }