中文題。
WA了不少次,其實spfa簡單可以過,關鍵是錯在建圖上了。正向建圖,設每個禮物爲t,每個禮物的自身價值別放在(t,t)上,放在(t,0)上,把0當作一個結束點去算。然後枚舉每一個可行的等級區間,把0的等級包括在枚舉的區間內,然後spfa,取每一次枚舉後dis[0]的最小值,即是答案。
代碼:
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
const int inf=0x3f3f3f3f;
int m,n;
int mm[105][105]={0};
int level[105]={0};
int dis[105];
bool had[105];
queue <int> q;
void spfa(int lv){
memset(dis,0x3f,sizeof(dis));
memset(had,0,sizeof(had));
dis[1]=0;
q.push(1);
while(!q.empty()){
int t=q.front(); q.pop();
had[t]=0;
for(int i=0;i<=n;i++){
if(level[i]>lv+m || level[i]<lv) continue;
if(dis[i]>dis[t]+mm[t][i]){
dis[i]=dis[t]+mm[t][i];
if(!had[i]){
had[i]=1;
q.push(i);
}
}
}
}
}
int main(){
//freopen("in.txt","r",stdin);
cin>>m>>n;
memset(mm,0x3f,sizeof(mm));
for(int i=1;i<=n;i++){
int t;
cin>>mm[i][0]>>level[i]>>t;
while(t--){
int t1,t2;
cin>>t1>>t2;
mm[i][t1]=t2;
}
}
int ans=inf;
for(int i=level[1]-m;i<=level[1];i++){
level[0]=i;
spfa(i);
if(ans>dis[0]) ans=dis[0];
}
cout<<ans<<endl;
return 0;
}