题意:最终目的是买10000的聘礼,一个商品可以直接按原价买也通过送上另一件商品加上一些金钱得到求最少用多少钱买到聘礼,但是这个部落等级森严,不能差距过大。
题解:可以从任何一个商品开始买到聘礼,因为最终都是买到聘礼,所以看成以聘礼为起点的单源最短路,但是等级差距用dijkstra不好处理,可以用dfs,虽然复杂度更高,但是当前的等级上下限可以用参数传递解决:dfs(x,value,low,up)中,x是当前搜到的点,value是这个点目前的消耗(不包括这个点)。
#include<cstdio> #include<cstring> #include<iostream> #define maxn 105 #define inf 10000000 using namespace std; int mp[105][105],vis[105],price[105],rank[105]; int limit,n,ans; int dfs(int x,int value,int up,int low){ int i; vis[x]=1; ans=min(ans,value+price[x]);//value+price是从这个点开始向聘礼开始买,所以要加上price for(i=1;i<=n;i++){ if(mp[x][i]==-1)continue; if(vis[i])continue; if(rank[i]<low&&rank[i]>=low-limit)dfs(i,value+mp[x][i],rank[i],up); else if(rank[i]>up&&rank[i]<=up+limit)dfs(i,value+mp[x][i],low,rank[i]); else dfs(i,value+mp[x][i],low,up); } vis[x]=0; return 1; } int main(){ int i,j,num,temp; scanf("%d%d",&limit,&n); for(i=1;i<=n;i++) for(j=1;j<=n;j++)mp[i][j]=-1; for(i=1;i<=n;i++){ scanf("%d%d%d",&price[i],&rank[i],&num); while(num--){ scanf("%d%d",&j,&temp); mp[i][j]=temp; } } ans= inf; dfs(1,0,rank[1],rank[1]); printf("%d\n",ans); return 0; }