【并查集】【贪心】supermarket

链接:

poj1456——supermarket

luoguUVA1316——supermarket


题目:

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


输入:

多组数据,每组先给出一个整数N,表示这批货的商品个数。

然后有N对数,每对数有两个用空格隔开的正整数 P i P_i Pi, D i D_i Di
​ ,表示第i个商品的收益和过期时间。相邻两对数之间用空格隔开。

输入以一个文件终止符结束,并且保证所有输入数据正确。


输出:

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


样例输入:

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

样例输出:

80 
185

思路:

这题我们用并查集来做,首先要对物品的价值排序(以便贪心),然后并查集看能不能买,然后累加一下答案,最后把父节点的指针指向前一个。


C o d e Code Code

#include
#include
#include
#include
using namespace std;
int n,gg,f[100000],ans;
struct node//排序用
{
	int w,p;
}e[1000001];
int find(int dep){return f[dep]<0?dep:f[dep]=find(f[dep]);}//并查集
bool px(node x,node y){return x.w>y.w;}
int main()
{
	while(scanf("%d",&n)!=EOF)//多组数据
	{
		ans=0;
		memset(f,-1,sizeof(f));//初始化(我也不知为啥要是-1【大汗)
		for(int i=1;i<=n;i++)
		scanf("%d%d",&e[i].w,&e[i].p);
		sort(e+1,e+1+n,px);//排序
		for(int i=1;i<=n;i++)
		{
			gg=find(e[i].p);//看能不能买
			if(gg)
			{
				ans+=e[i].w;//累加
				f[gg]=gg-1;//指向前一个
			}
		}
		printf("%d\n",ans);//输出
	}
	return 0;
} 

你可能感兴趣的:(贪心,并查集)