poj 1062 dijkstra求最短路变形

题目大意是说有N个物品,每个物品都有自己的价格,但同时某些物品也可以由其他的(可能不止一个)替代品,这些替代品的价格比较“优惠”,问怎么样选取可以让你的花费最少来购买到物品1

由于有N个物品,我们就可以把它们看作是N个点,从其他点到他的优惠关系视做边,又因为最后总是要找到物品1,然后由于题目是说,这条路劲上不能有两个的等级差超过M,所以我们可以枚举最小等级,将每个点视作最小等级,这样的话就不会掉解。枚举最小等级,然后把等级比他小或者不符合最大限制的点删去,然后在剩下的符合要求的点中再求dij即可。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define mp make_pair
#define x first
#define y second
const int INF=0x3f3f3f3f;
const int N=100+9;
int w[N][N],d[N],p[N],l[N];
bool vis[N];
int n;
int dij()
{
    for(int i=1;i<=n;i++)d[i]=p[i];
    for(int i=1;i<=n;i++){
        int x,m=INF;
        for(int j=1;j<=n;j++)if(!vis[j]&&d[j]<=m)m=d[x=j];
        vis[x]=1;
        for(int j=1;j<=n;j++)if(!vis[j])d[j]=min(d[j],d[x]+w[x][j]);
    }
    return d[1];
}
int main()
{
    int m,X,T,V,minn=INF;
    scanf("%d%d",&m,&n);
    memset(w,0x3f,sizeof(w));
    for(int i=1;i<=n;i++){
        scanf("%d%d%d",&p[i],&l[i],&X);
        while(X--){
            scanf("%d%d",&T,&V);
            w[T][i]=V;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(l[i]+m<l[j]||l[j]<l[i])vis[j]=1;
            else vis[j]=0;
        }
        minn=min(minn,dij());
    }
    printf("%d\n",minn);
    return 0;
}


posted @ 2016-07-06 19:22  HARD_UNDERSTAND  阅读(196)  评论(0编辑  收藏  举报