poj 1062:酋長的聘禮

中文題。


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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章