也是看了别人的讲解才懂得 之前 将1 作为源点 有点蠢 然后枚举路线也没想出来 之前总是想 在算的时候维持一条正确的路线 但是好难啊 以后要换换思路 将可能的源点列出来 把不合适的路线当作访问过 不对他优化 也不会找到他 然后再跑 就可以了 所以代码是
#include <iostream>
#include <cstdio>
#include <cstring>
#define MAXN 101
#define inf (1<<30)
using namespace std;
int m,n,r[MAXN][MAXN],level[MAXN],price[MAXN],d[MAXN];
bool visi[MAXN];
void read()
{
memset(r,0,sizeof(r));
scanf("%d %d",&m,&n);
int x,y,tp;
for(int i=1;i<=n;++i)
{
scanf("%d %d %d",&price[i],&level[i],&x);
r[0][i]=price[i];
d[i]=inf;
for(int j=1;j<=x;++j)
{
scanf("%d %d",&y,&tp);
r[y][i]=tp;
}
}
}
int dij()
{
for(int i=1;i<=n;++i)
d[i]=price[i];
for(int j=1;j<=n;++j)
{
int x=0,u=inf;
for(int i=1;i<=n;++i)
if(!visi[i]&&d[i]<u)
u=d[x=i];
if(x==0)
break;
visi[x]=true;
for(int i=1;i<=n;++i)
if(!visi[i]&&r[x][i]>0)
d[i]=min(d[i],d[x]+r[x][i]);
}
return d[1];
}
int main()
{
read();
int temp=inf,ans=inf;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
if(level[i]<level[j]||level[i]-level[j]>m)
visi[j]=true;
else
visi[j]=false;
}
temp=dij();
ans=min(temp,ans);
}
cout<<ans<<endl;
return 0;
}