POJ1456&&UVA1316&&ybtoj【图论】1章5题【Supermarket】

Supermarket

题目

Supermarket


解析

其实这题最方便的解法是优先队列,但是用并查集也未必不可,思路如下:
1,先按价值大小>,再按过期时间<进行快排(贪心)
2,初始化并查集
3,对于每一天,建立两个域,分别代表他的父节点和这个点的价值(记得每次初始化)
4,按顺序判断,如果能卖这个东西就卖掉,这一天的价值就为该物品的价值,将这一天指向昨天即可
不幸的是,蒟蒻这题有双倍经验,但没有三倍经验血亏,因为UVA评测的速度有口皆碑

code:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,f[10010],s[10010],tot,sum,k;
struct node
{
    
    
	int d,p;
}a[10010];
int find(int dep)
{
    
    
	if(f[dep]==dep)return dep;
	return f[dep]=find(f[dep]);
}
bool cmp(node x,node y){
    
    if(x.p!=y.p)return x.p>y.p;return x.d<y.d;}
int main()
{
    
    
	while(cin>>n)
	{
    
    
		memset(s,0,sizeof(s));//初始化
		tot=sum=0;
		for(int i=1;i<=n;i++){
    
    scanf("%d%d",&a[i].p,&a[i].d);if(tot<a[i].d)tot=a[i].d;}
		for(int i=1;i<=tot;i++)f[i]=i;//初始化
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<=n;i++)
		{
    
    
			k=find(a[i].d);
			if(!s[k]&&k)//判断能不能卖
			{
    
    
				s[k]=a[i].p;
				f[k]=k-1;
			}
		}
		for(int i=1;i<=tot;i++)sum+=s[i];//求和
		printf("%d\n",sum);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/113027095