POJ 1062 昂贵的聘礼

题意:中文题……

 

解法:dijkstra。建图建不明白了……绕了好久……最终目标是买1号物品,那么以1为起点,求到所有点的最短路,边权为优惠价格,一条路的最小值为这条路所有边权之和加终点的价格。对于等级的限制条件,每次枚举一个等级区间,只计算区间内点的最短路。

 

代码:dijkstra又是我自己照流程写的……目测很屎= =但是又懒得找模板……

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
struct node
{
    int v, val;
    node(int v, int val) : v(v), val(val) {}
    node() {}
};
vector <node> v[105];
int price[105];
int level[105];
int dis[105];
bool vis[105];
int n, m;
const int inf = 100000000;
void dij(int l)
{
    for(int i = 0; i < 105; i++)
    {
        dis[i] = inf;
        vis[i] = 0;
    }
    if(level[1] < l || level[1] > l + m) return;
    dis[1] = 0;
    vis[1] = 1;
    int len = v[1].size();
    for(int i = 0; i < len; i++)
    {
        int u = v[1][i].v;
        if(level[u] < l || level[u] > l + m) continue;
        dis[u] = v[1][i].val;
    }
    while(1)
    {
        int u = -1, minn = inf;
        for(int i = 1; i <= n; i++)
        {
            if(!vis[i] && (level[i] >= l && level[i] <= l + m))
            {
                if(dis[i] < minn)
                {
                    minn = dis[i];
                    u = i;
                }
            }
        }
        if(u == -1) break;
        vis[u] = 1;
        for(int i = 0; i < v[u].size(); i++)
        {
            int tmp = v[u][i].v;
            if(level[tmp] >= l && level[tmp] <= l + m)
            {
                dis[tmp] = min(dis[tmp], v[u][i].val + dis[u]);
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d", &m, &n))
    {
        for(int i = 0; i < 105; i++)
            v[i].clear();
        int minn = inf, maxn = 0;
        for(int i = 1; i <= n; i++)
        {
            int num;
            scanf("%d%d%d", &price[i], &level[i], &num);
            minn = min(level[i], minn);
            maxn = max(level[i], maxn);
            for(int j = 0; j < num; j++)
            {
                int a, b;
                scanf("%d%d", &a, &b);
                v[i].push_back(node(a, b));
            }
        }
        int ans = inf;
        minn = max(minn, level[1] - m);
        for(int i = minn; i <= maxn; i++)
        {
            dij(i);
            for(int j = 1; j <= n; j++)
                ans = min(ans, dis[j] + price[j]);
        }
        printf("%d\n", ans);
    }
    return 0;
}

  

posted @ 2015-08-12 13:18  露儿大人  阅读(88)  评论(0编辑  收藏  举报