POJ1062昂贵的聘礼 枚举最短路spfa

网址:http://poj.org/problem?id=1062
首先是建图。以编号0为搜索起点,以酋长物品(编号1)为终点求最短路。编号0到任意一个点的边权值为该物品原本的价值。非零点之间的权值为优惠后的价格。
因为有等级限制,所以有的点没办法经过。所以要假设一个等级为最小的等级,枚举这些最小等级,枚举后最小的长度就是结果。
我用的spfa方法

#include
#include
#include
#include
#include
using namespace std;
#define INF 0x3f3f3f3f
#define MAX 200+5
#define N 5000+5
#define mem(arr,a) memset(arr,a,sizeof(arr))
int n, m;
int d[N];
int cost[MAX][MAX];
int vis[N];
int use[N];
int money, ranks[N], rep;
int spfa(){
    mem(d, INF);
    d[0] = 0;
    mem(use, 0);
    queue<int>q;
    q.push(0);
    while (!q.empty()){
        int u = q.front(); q.pop(); use[u] = 0;
        for (int i = 1; i <= m; i++){
            if (!vis[i] && d[i] > d[u] + cost[u][i]){
                d[i] = d[u] + cost[u][i];
                if (!use[i]){
                    use[i] = 1;
                    q.push(i);
                }
            }
        }
    }
    return d[1];
}
void build(){
    int minflow = INF;
    for (int i = 1; i <= m; i++){
        int maxranks = ranks[i];
        mem(vis, 0);
        for (int j = 1; j <= m; j++){
            if (maxranksn)vis[j] = 1;
        }
        minflow = min(minflow, spfa());
    }
    cout << minflow << endl;

}
int main(){
    while (cin >> n >> m)
    {
        mem(cost, INF);
        for (int i = 1; i <= m; i++){
            cin >> money >> ranks[i] >> rep;
            for (int j = 1; j <= rep; j++){
                int t, v; cin >> t >> v;
                cost[t][i] = v;
            }
            cost[0][i] = money;
        }
        build();
    }
}

你可能感兴趣的:(最短路)