zoukankan      html  css  js  c++  java
  • poj1062

    题意:每个人都有一个物品,对应一定的钱数,想要得到此物品可以直接出钱,也可以通过用其他人的物品并添加一些钱来交换,问要得到酋长的物品最少需要多少钱?另外,每个人都有一个等级,要求和你交易的人中不能有任何两人的等级相差m以上。

    分析:我们可以把本题理解为,我们要买一号物品,而一个物品的一部分价值可以转化为别的物品,我们通过购买别的物品和加钱来购买获得一号物品。所以我们可以把需要加的钱数作为该物品到别的物品的一条边,走过这条边,我们要花一些钱,然后我们只需要购买现在所在结点的物品即可。这样就把问题转化为最短路问题,用dijkstra就可以了。

    本题还有个等级制度的问题。我们可以每次枚举一个宽为m的等级区间,忽略不在区间内的点,进行dijkstra。

    我wrong answer是因为第一次没处理起始点不在枚举的区间内的情况。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 101, inf = 1000000000;
    
    struct Item
    {
    	int p, l;
    } item[maxn];
    
    struct Edge
    {
    	int v, w;
    	Edge()
    	{
    	}
    	Edge(int vv, int ww) :
    		v(vv), w(ww)
    	{
    	}
    } e[maxn * maxn];
    
    int map[maxn], level[maxn], levelnum = 0, dist[maxn];
    int n, m;
    bool vis[maxn];
    
    void dijkstra(int floor)
    {
    	int best = 0, besti = 0;
    	int d[maxn];
    
    	for (int i = 0; i <n; i++)
    	{
    		d[i] = inf;
    		vis[i] = false;
    	}
    	d[0] = 0;
    	while (besti != -1)
    	{
    		vis[besti] = true;
    		for (int i = map[besti]; i < map[besti + 1]; i++)
    		{
    			if (d[e[i].v] > best + e[i].w && item[e[i].v].l >= floor && item[e[i].v].l <= floor + m)
    			{
    				d[e[i].v] = best + e[i].w;
    			}
    		}
    		best = inf;
    		besti = -1;
    		for (int i = 0; i < n; i++)
    			if (!vis[i] && d[i] < best)
    			{
    				best = d[i];
    				besti = i;
    			}
    	}
    	for (int i = 0; i < n; i++)
    		if (dist[i] > d[i])
    			dist[i] = d[i];
    }
    
    int main()
    {
    	//freopen("D:\\t.txt", "r", stdin);
    	scanf("%d%d", &m, &n);
    	for (int i = 0; i < n; i++)
    		dist[i] = inf;
    	map[0] = 0;
    	for (int i = 0; i < n; i++)
    	{
    		int temp;
    		scanf("%d%d%d", &item[i].p, &item[i].l, &temp);
    		level[levelnum++] = item[i].l;
    		map[i + 1] = map[i] + temp;
    		for (int j = 0; j < temp; j++)
    		{
    			int a, b;
    			scanf("%d%d", &a, &b);
    			a--;
    			e[map[i] + j] = Edge(a, b);
    		}
    	}
    	sort(level, level + levelnum);
    	levelnum = unique(level, level + levelnum) - level;
    	for (int i = 0; i < levelnum; i++)
    		if (item[0].l >= level[i] && item[0].l <= level[i] + m)
    		dijkstra(level[i]);
    	int ans = inf;
    	for (int i = 0; i < n; i++)
    		if (ans > dist[i] + item[i].p)
    			ans = dist[i] + item[i].p;
    	printf("%d\n", ans);
    	return 0;
    }
  • 相关阅读:
    UUID工具类
    jax-rs 标准以及 结合 resteasy的使用
    Mina.Net实现的断线重连
    Mina.Net实现的UDP协议消息收发Demo
    MySql 比Replace Into更适合的用法,外加SqlServer的方式。
    MySql【Insert Select Not Exist】判断记录再添加值的方案
    MySql中存储过程中的@变量总是无法执行,提示Parameter '@XXX' must be defined
    Go语言使用Beego的ORM插入Mysql后,时区不一致的解决方案
    Go语言中Path包用法
    C#(WPF和WinForm)在普通类中调用到主线程的方法,SynchronizationContext的用法。
  • 原文地址:https://www.cnblogs.com/rainydays/p/1948670.html
Copyright © 2011-2022 走看看