从这个题可以学到对于题目中如果有 约束条件 来约束 图中两点之间可行性的时候 可以用哪些方法解决
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
// 注意优惠价格的意思是 这个物品将可以用这个价格买下 而不是 优惠了这多价格
// 我就说怎么变不成最短路
// 然后还要在注意一下区间的问题 一定是在合法的等级区间内进行相应的 遍历
// 对于这个区间的问题 可以用vis数组标记来起到把不合法的点去掉 不访问 也可以通过区间的思想 越界之后直接返回即可
//https://blog.csdn.net/weixin_44339734/article/details/104257424 第二种方法参考这篇博客
using namespace std;
#define inf 0x3f3f3f3f
typedef long long ll;
// 有些能够窥见 图论 难的不是算法的应用 而是 图的建立和约束条件如何能够实现的
const int N = 107;
int m,n;
int price[N];//每件物品的价格 记录下来方便从0点走的价格的记录
int mp[N][N];
int dis[N],vis[N];
int level[N];// 每件物品的等级为多少
void init()
{
memset(price,0,sizeof(price));
memset(level,0,sizeof(level));
for(int i = 0;i <= n;i ++)
{
for(int j = 0;j <= n;j ++)
{
if(i != j)
mp[i][j] = inf;
else
mp[i][j] = 0;
}
}
}
int dijkstra()
{
//memset(vis,0,sizeof())
for(int i = 1;i <= n;i ++)
{
dis[i] = mp[0][i];
}
vis[0] = 1;
for(int i = 1;i <= n;i ++)
{
int minn = inf;
int temp;
for(int j = 1;j <= n;j ++)
{
if(dis[j] < minn && vis[j] == 0)
{
minn = dis[j];
temp = j;
}
}
vis[temp] = 1;
for(int j = 1;j <= n;j ++)
{
if(dis[j] > mp[temp][j] + dis[temp] && !vis[j])// 这个地方和一般的不同 因为这里的vis 不仅记录了 是否找过 还代表着是否符合 合法的区间
dis[j] = mp[temp][j] + dis[temp];
}
}
return dis[1];
}
int main()
{
while(scanf("%d%d",&m,&n) != EOF)
{
init();
int p,x;
for(int i = 1;i <= n;i ++)
{
scanf("%d%d%d",&p,&level[i],&x);
while(x--)
{
int s,w;
scanf("%d%d",&s,&w);
mp[s][i] = w;
}
mp[0][i] = p;// 因为最先给出的1点相当于终点 所以可以把0点看做我们的起点 然后去找 1
}
int ans = inf;
for(int i = 1;i <= n;i ++)
{
memset(dis,0,sizeof(dis));
int tmp = level[i];
for(int j = 1;j <= n;j ++)
{
if(level[j] < tmp || level[j] - tmp > m)
vis[j] = 1;
else
vis[j] = 0;
}
int res = dijkstra();
ans = min(ans,res);
}
printf("%d\n",ans);
}
return 0;
}