1. 程式人生 > >POJ 1456 Supermarket【貪心+並查集】

POJ 1456 Supermarket【貪心+並查集】

Supermarket
Time Limit:2000MS Memory Limit:65536K
Total Submissions:11450 Accepted:5053

Description

A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σx∈Sell
px. An optimal selling schedule is a schedule with a maximum profit.
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80.

Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products.

Input

A set of products starts with an integer 0 <= n <= 10000, which is the number of products in the set, and continues with n pairs pi di of integers, 1 <= pi <= 10000 and 1 <= di <= 10000, that designate the profit and the selling deadline of the i-th product. White spaces can occur freely in input. Input data terminate with an end of file and are guaranteed correct.

Output

For each set of products, the program prints on the standard output the profit of an optimal selling schedule for the set. Each result is printed from the beginning of a separate line.

Sample Input

4  50 2  10 1   20 2   30 1

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

Sample Output

80
185

Hint

The sample input contains two product sets. The first set encodes the products from table 1. The second set is for 7 products. The profit of an optimal schedule for these products is 185.

Source

Southeastern Europe 2003

題目大意:有n個商品,每個商品都有一個值,第一個是其價值,第二個是其過期日期,每一天只能賣一件商品,問最大利潤。

思路:

按照商品價值從高到低排序,然後從高到低遍歷,如果當前商品的截止日期沒有分配任務,那麼就在這個日期上分配當前商品任務,如果截止日期上已經分配了商品任務了,就向前遍歷日期,看哪一天空閒,然後在這個空閒的日期上分配當前商品任務,如果從當前商品任務的截止日期到第一天都有商品任務分配了,那麼就說明這個商品任務沒有必要完成了。

網上看到有很多大牛用並查集來優化問題,嘗試了一發,的確是快了很多,具體操作為這樣:

初始的時候,將每個f【】都設定自身為根節點,在遍歷當前任務的時候,令ff=find(a【i】.day),如果ff>0那麼設定上這個日期分配當前任務,並且使得f【ff】=ff-1,這樣就達成了上述最開始思路的操作了。

AC程式碼:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
struct node
{
    int val,day;
}a[100000];
int f[100000];
int cmp(node a,node b)
{
    return a.val>b.val;
}
int find(int a)
{
    int r=a;
    while(f[r]!=r)
    r=f[r];
    int i=a;
    int j;
    while(i!=r)
    {
        j=f[i];
        f[i]=r;
        i=j;
    }
    return r;
}
void merge(int a,int b)
{
    int A,B;
    A=find(a);
    B=find(b);
    if(A!=B)
    f[B]=A;
}
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        int maxday=0;
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&a[i].val,&a[i].day);
            maxday=max(maxday,a[i].day);
        }
        int output=0;
        for(int i=1;i<=maxday;i++)f[i]=i;
        sort(a,a+n,cmp);
        for(int i=0;i<n;i++)
        {
            int ff=find(a[i].day);
            if(ff>0)
            {
                f[ff]=ff-1;
                output+=a[i].val;
            }
        }
        printf("%d\n",output);
    }
}