ACM-图论-Dijsktra Poj1062

我是看了别人的题解,以下附上链接:
点这里看具体题解
中文题:我就解释一下样例

输入:
输入第一行是两个整数M,N1 <= 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
以下是最短路途径
物品450)不可替代,必须付50,sum+=50
物品33000)可以用物品450)+200付款,sum+=200
物品110000)可以用物品33000)+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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值