链接:
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对数,每对数有两个用空格隔开的正整数
,
,表示第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
思路:
这题我们用并查集来做,首先要对物品的价值排序(以便贪心),然后并查集看能不能买,然后累加一下答案,最后把父节点的指针指向前一个。
:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
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;
}