【并查集】Supermarket(poj 1456/luogu-UVA1316)

Supermarket

poj 1456

luogu-UVA1316

题目大意:

有一堆物品,每一件物品都有自己的价值和保质期,每天只能卖出一件物品,问最大价值是多少

原题:

题目描述

有一个商店有许多批货,每一批货又有 N ( 0 < = N < = 1 0 4 ) N(0<=N<=10^4) N(0<=N<=104个商品,同时每一样商品都有收益 P i P_i Pi ,和过期时间 D i D_i Di ( 1 < = P i , D i < = 1 0 4 ) (1<=Pi,Di<=10^4) (1<=Pi,Di<=104),一旦超过了过期时间,商品就不能再卖。
你要做的就是求出每批货最多能得到多少收益。

输入输出格式

输入格式

多组数据,每组先给出一个整数N,表示这批货的商品个数。
然后有N对数,每对数有两个用空格隔开的正整数 P i , D i P_i,D_i Pi,Di ,表示第i个商品的收益和过期时间。相邻两对数之间用空格隔开。
输入以一个文件终止符结束,并且保证所有输入数据正确。

输出格式

对于每组数据,输出一行一个整数表示该批货物能卖出的最大价格。
输入输出样例

输入样例#1:

4 50 2 10 1 20 2 30 1
7 20 1 2 1 10 3 100 2 8 2 5 20 50 10

输出样例#1:

80 
185

解题思路:

我们可以用类似贪心的方法来做,先用价值来排序,然后可以买的就买,然后用保质期来并查集,如果买了,那当前单位时间就不能买了,只能在上一个单位时间买,就指向上一个单位时间

代码:

#include
#include
#include
#include
using namespace std;
int n,k,ans,dad[10005];
struct rec
{
	int s,l;
}a[10005];
bool cmp(rec xx,rec yy){return xx.s>yy.s;}
int find(int dep){return dad[dep]<0?dep:dad[dep]=find(dad[dep]);}
int main()
{
	while(scanf("%d",&n)!=EOF)
	  {
	  	ans=0;
	  	memset(dad,-1,sizeof(dad));//与出路
	  	for (int i=1;i<=n;++i)
	  	  scanf("%d %d",&a[i].s,&a[i].l);
	  	sort(a+1,a+1+n,cmp);//排序
	  	for (int i=1;i<=n;++i)
	  	  if (k=find(a[i].l))//判断是否可以卖
	  	    ans+=a[i].s,dad[k]=k-1;//买下来,并且当前时间不能再买
	  	printf("%d\n",ans);
	  }
}

你可能感兴趣的:(图论,并查集)