我是看了别人的题解,以下附上链接:
点这里看具体题解
中文题:我就解释一下样例
输入:
输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠价格"。
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0
输出:输出最少需要的金币数。
5250
1.样例解释
sum=0
以下是最短路途径
物品4(50)不可替代,必须付50,sum+=50
物品3(3000)可以用物品4(50)+200付款,sum+=200
物品1(10000)可以用物品3(3000)+5000付款,sum+=5000
sum=50+200+5000=5250
2.初始化
#define inf 1000000007
int s,n,m;
int dis[110],edge[110][110],deng[110],price[110];
bool vis[110];
void init(){
memset(price,0,sizeof(price));//必须初始化 !!!!!!!!!!
memset(deng,0,sizeof(deng));
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
edge[i][j]=inf;//是无向图记得取反
}
}
}
3.dijsktra
int dij(){
for(int i=1;i<=n;i++)dis[i]=edge[0][i];//全改成dis--->edge/price!!!
for(int i=1;i<=n;i++){//<n
int cur=0,temp=inf;
for(int j=1;j<=n;j++){
if(!vis[j]&&temp>=dis[j]){//>
temp=dis[j];
cur=j;
}
}
vis[cur]=1;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]>dis[cur]+edge[cur][j]){
dis[j]=dis[cur]+edge[cur][j];
}
}
}
return dis[1];
}
4.main
int main(){
int z=1;
freopen("2.txt","r",stdin);
while(scanf("%d %d",&m,&n)!=EOF){
init();
//关键!!!!!初始化edge
for(int i=1;i<=n;i++){//酋长的i物品是1
int u,t,v;
scanf("%d %d %d",&price[i],&deng[i],&u);
while(u--){
scanf("%d %d",&t,&v);
edge[t][i]=v;
}
edge[0][i]=price[i];//直接金钱付
}
//枚举等级
int ans=inf;
for(int i=1;i<=n;i++){
int minlev=deng[i];//第一个接触的人
for(int j=1;j<=n;j++){//第二个可以接触的人vis设置
//地位差距超过一定限制的两个人之间不会进行任何形式的直接接触
//他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易
if(deng[j]<minlev||deng[j]-minlev>m)vis[j]=1;
else vis[j]=0;
}
int p=dij();
ans=min(p,ans);
}
printf("%d\n",ans);
}
return 0;
}