比普通模板题稍微深入一些些的模板题,物品和物品之间的互换关系完全可以理解成图上的路, 求最小价格自然也就是求从1点到某一点的最短路问题了,难点只在于建图。
很显然不论如何,最短路中顶点必须包含1。所以等级范围必定包含lv[1](即酋长的等级),那么只要对包含lv[1]的范围进行遍历即可。
在这里用的是很香很香的SPFA解法,储存方式是链式前向星。
要注意的点不多,数组不要开太大会MLE,然后就是注意多组输入。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<string> #include<stack> #include<queue> #include<vector> #include<cstdlib> //#include<windows.h> #define first fi #define second se using namespace std; typedef long long ll; const int N = 1e4+10; const int INF = 0x3f3f3f3f; const int inf = - INF; const int mod = 1e9+7; const double pi = acos(-1.0); int ver[N],edge[N],dist[N],head[N],Next[N]; int p[N],l[N]; int vis[N],low,lim; int tot=0; int M,n; void add(int u,int v,int w){ ver[++tot]=v; edge[tot]=w; Next[tot]=head[u]; head[u]=tot; } int SPFA(int s,int e){ for(int i=1;i<=n;i++) dist[i]=p[1]; dist[s]=0; queue<int>q; q.push(s); vis[s]=1; while(q.size()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i;i=Next[i]){ int v=ver[i]; int w=edge[i]; if(l[v]>=low&&l[v]<=lim&&(dist[v]>dist[u]+w)){ dist[v]=dist[u]+w; if(!vis[v]){ q.push(v); vis[v]=1; } } } } return dist[e]; } int main() { while(~scanf("%d%d",&M,&n)) { memset(dist,INF,sizeof(dist)); memset(head,0,sizeof(head)); for(int i=1;i<=n;i++){ int x; scanf("%d%d%d",&p[i],&l[i],&x); add(0,i,p[i]); for(int j=0;j<x;j++){ int a,b; scanf("%d%d",&a,&b); add(a,i,b); } } int minn=INF,flag=0; for(int i=l[1]-M;i<=l[1];i++){ low=i; lim=i+M; memset(vis,0,sizeof(vis)); flag=SPFA(0,1); minn=(flag<minn)?flag:minn; } printf("%d\n",minn); } //system("pause"); return 0; }