昂贵的聘礼(SPFA最短路)

最短路问题,建图(有向图),以1点为源点,枚举等级的限制,即每次都用spfa 求得1点到其他能够到达的点(由于等级的限制,在一次spfa中可能并不是所有的点都能够到达),最后求出所需最小费用。


#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

#define Max 110
#define levelInit -1
#define visitInit false
#define peopleInit -1
#define priceInit 9999999
#define start 1

int peopleToPeople[Max][Max];
int changePrice[Max];
int level[Max];
bool visit[Max];
int price[Max];

int n; int m;
queue< int > Q;


void init(){    
    
    int p      = priceInit;
    int l      = levelInit;
    int num    = 0;
    int index  = 0;
    int indexP = 0;
    
    memset( level,          levelInit,  sizeof( level ) );
    memset( visit,          visitInit,  sizeof( visit ) );
    memset( peopleToPeople, peopleInit, sizeof( peopleToPeople ) );
    memset( changePrice,    priceInit,  sizeof( changePrice ) );
    memset( price,          priceInit,  sizeof( price ) );
    
    for( int i = 1; i <= n; ++i ){
        
        cin >> p >> l >> num;
        level[i] = l;
        price[i] = p;
        
        for( int j = 1; j <= num; ++j ){
            
            cin >> index >> indexP;
            peopleToPeople[i][index] = indexP;            
            
        }
    }
}


void SPFA(){
    
    visit[start]       = true;
    changePrice[start] = 0;
    
    Q.push( start );
    
    while( !Q.empty() ){
        
        int index = Q.front();
        Q.pop();
        visit[index] = false;
        
        for( int i = 1; i <= n; ++i ){
            if( peopleToPeople[index][i] != peopleInit && 
                peopleToPeople[index][i] + changePrice[index] < changePrice[i] ){
                   
                changePrice[i] = peopleToPeople[index][i] + changePrice[index];
                
                if(visit[i] == false){
                    
                    visit[i] = true;
                    Q.push( i );                                        
                    
                }
            }
        }
    }
}


int main(){
    
    cin >> m >> n;
    
    init();
    SPFA();
    
    const int lev = level[start];
    int minPrice  = priceInit;
    
    for( int i = 1; i <= n; ++i ){
        
        changePrice[i] += price[i];
        
        if( minPrice > changePrice[i] && 
           lev - level[i] <= m && 
           lev - level[i] >= 0) 
           minPrice = changePrice[i];
           
    }
    
    cout << minPrice << endl;
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值