Poj1456并查集

线段树可以搞搞,按端点排个序,然后每次找端点以内最大的,然后删除。

学了下并查集的搞法。先按价值贪心,每次拿走一个价值的时候,将这个价值所在集合的日期,推前一天,表示接下来日期在这段数内的物品只能在这段时间之前取,这个物品能取得日期为0的时候代表没法取了。

#pragma comment(linker,"/STACK:102400000,102400000") 
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<string>
#include<queue>
#include<stack>
#include<list>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#include<map>
#include<cstring>
#include<set>
using namespace std;
typedef long long LL;
const int maxn = 11111;
int father[maxn];
int getfather(int x)
{
    if (x != father[x]) father[x] = getfather(father[x]);
    return father[x];
}

struct Node
{
    int a; int b;
}node[maxn];
int cmp(const Node &a, const Node &b)
{
    return a.a > b.a;
}
int main()
{
    int n;
    while (scanf("%d", &n) != EOF) {
        for (int i = 0; i < n; i++) scanf("%d%d", &node[i].a, &node[i].b);
        sort(node, node + n, cmp);
        int ans = 0;
        for (int i = 1; i < 11111; i++) father[i] = i;
        for (int i = 0; i < n; i++) {
            int fa = getfather(node[i].b);
            if (fa > 0) {
                ans += node[i].a;
                father[fa] = fa - 1;
            }
        }
        cout << ans << endl;
    }
    return 0;
}

 

posted on 2015-08-14 16:57  一个西瓜  阅读(466)  评论(0编辑  收藏  举报

导航