题目传送门

//此题的关键在于等级限制的处理,最好的办法是采用枚举,即假设酋长等级为5,等级限制为2,那么需要枚举等级从3~5,4~6,5~7
//然后就是dij了,至于为什么要用dij,看个人喜好,毕竟这里等级处理要对vis数组进行标记
//处理了等级问题,就可以枚举等级数组,n倍dij跑完本题了,nlogn0ms搞定
//以下为具体代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

#define inf 0x3fffffff
int maze[110][110];
int dis[110],degree[110],val[110],vis[110];
int m,n;
void init()
{
    memset(dis,inf,sizeof(dis));
    for(int i=1;i<=n;i++)
       for(int j=1;j<=n;j++)
          maze[i][j]=inf;
}

int dij()
{
    for(int i=1;i<=n;i++)
        dis[i]=val[i];
    for(int i=1;i<=n;i++)
    {
        int minn=inf,mark=inf;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]<minn)
            {
                minn=dis[j];
                mark=j;
            }
        }
        if(minn==inf)break;
        vis[mark]=true;
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]>dis[mark]+maze[mark][j])
            {
                dis[j]=dis[mark]+maze[mark][j];
            }
        }
    }
    return dis[1];
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        init();
        int x,a,b,tmp;
        int ans=inf;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d",&val[i],&degree[i],&x);
            while(x--)
            {
                scanf("%d%d",&a,&b);
                maze[a][i]=b;
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(degree[j]>=degree[i]&&degree[j]<=degree[i]+m)
                {
                    vis[j]=false;
                }
                else
                {
                    vis[j]=true;
                }
            }
            tmp=dij();
            ans=min(ans,tmp);
        }
        cout<<ans<<endl;
    }
    return 0;
}