poj1062 昂贵的聘礼 最短路

19 篇文章 0 订阅

PS:中文题太爽了。。

题意:中文题我就不写题意了。。。

分析:我感觉要注意两点。。。1.注意等级限制,我本来以为只有在相邻的两个人物中有等级的限制,其实在你需要交换的所有人都有等级的限制。。。2.建图要建有向图。。不是无向图。。我因为这个哇了半天。。。

具体做法就是,建图,然后枚举dijk

代码:


#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

#define inf (0x3f3f3f3f)
const int maxn = 105;

int m, n;
struct Goods
{
	int p, l, v;
	int num[maxn];
	int val[maxn];
}goods[maxn];
int map[maxn][maxn];

int dijk(int x)
{
	int i, j;
	int level = goods[x].l;
	int cost[maxn];
	bool vis[maxn];
	memset(cost, inf, sizeof(cost));
	memset(vis, false, sizeof(vis));
	for (i=0; i<=n; i++)
	{
		if (goods[i].l - level <= m && goods[i].l >= level)
			cost[i] = map[0][i];
	}
	vis[0] = true;
	for (i=0; i<n; i++)
	{
		int min = inf, imin;
		for (j=0; j<=n; j++)
		{
			if (!vis[j] && cost[j] < min)
			{
				imin = j;
				min = cost[j];
			}
		}
		if (min == inf)
			break;
		vis[imin] = true;
		
		for (j=0; j<=n; j++)
		{
			if (goods[j].l - level <= m && goods[j].l >= level)
				if (cost[j] > cost[imin] + map[imin][j])
					cost[j] = cost[imin] + map[imin][j];
		}
	}
	return cost[1];
}

int main()
{
	while (scanf("%d %d", &m, &n) != EOF)
	{
		memset(goods, 0, sizeof(goods));
		memset(map, inf, sizeof(map));
		int i, j;
		for (i=1; i<=n; i++)
		{
			scanf("%d %d %d", &goods[i].p, &goods[i].l, &goods[i].v);
			for (j=0; j<goods[i].v; j++)
			{
				scanf("%d %d", &goods[i].num[j], &goods[i].val[j]);
			}
			map[0][i] = goods[i].p;
		}
		for (i=1; i<=n; i++)
		{
			for (j=0; j<goods[i].v; j++)
			{
				if (abs(goods[goods[i].num[j]].l - goods[i].l) <= m)
				{ 
					if (map[goods[i].num[j]][i] > goods[i].val[j])
					{
						map[goods[i].num[j]][i] = goods[i].val[j];
					}
				}
			}
		}
		int min = inf;
		for (i=1; i<=n; i++)
		{
			int tmp = dijk(i);
			if (tmp < min)
				min = tmp;
		}
		printf("%d\n", min);
	}
	return 0;
}

网上大牛的测试数据:

测试数据1:
1 4
10000 3 2
2 8000
3 5000
1000 2 1
4 200
3000 2 1
4 200
50 2 0

5250

测试数据2:
1 5
10000 3 4
2 3000
3 2000
4 2000
5 9000
8000 2 3
3 5000
4 2000
5 7000
5000 1 0
2000 4 1
5 1900
50 1 0

4000
测试数据3:
3 8
10000 3 6
2 3000
3 2000
4 2000
5 9000
7 1000
8 5008
8000 2 3
3 5000
4 2000
5 7000
5000 1 1
6 1000
2000 4 1
5 1900
50 1 0
5000 1 1
7 4007
2000 4 1
5 1900
80 3 0

2950
测试数据4:
1 10
1324 0 0
1234 0 0
255 0 0
67 0 0
56 0 0
2134 0 0
456 0 0
2345 0 0
67 0 0
6436 0 0

1324

测试数据5:
1 4
10000 3 2
2 1
3 3
1000 2 2
4 1
3 1
1000 3 1
4 2
100 4 0

105
测试数据6:
3 5
10000 3 4
2 3000
3 2000
4 2000
5 9000
8000 2 3
3 5000
4 2000
5 7000
5000 1 0
2000 4 1
5 1900
50 1 0

3950



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值