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;
    }
  • 相关阅读:
    HTML5简易在线画图工具
    HTML Canvas 鼠标画图
    [转]javascript中style.left和offsetLeft的使用
    android中如何获取指定目录下的图片
    Android开发——Android中常见的4种线程池(保证你能看懂并理解)
    Android 文件的读取和写入
    MediaPlayer: Couldn't open /storage/emulated/0/kgmusic/download/独家记忆.mp3: java.io.FileNotFoundExcept
    Android开发-各种各样好看漂亮的进度条,指示器,加载提示汇总
    FileUriExposedException_Android7.0适配
    根据Uri获取文件的绝对路径
  • 原文地址:https://www.cnblogs.com/rainydays/p/1948670.html
Copyright © 2011-2022 走看看