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

来源:互联网 发布:excel宏的编程实例 编辑:程序博客网 时间:2024/05/17 01:47

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

#include<iostream>#include<queue>#include<string>#include<algorithm>#include<cmath>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 (maxranks<ranks[j] || maxranks - ranks[j]>n)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();    }}