翻译出来这道题目后首先想到的就是线段树,因为线段树可以很好的处理在di天前面还剩多少天,然后找出来距离di最近的,不过这既然是并查集专题,就不得不使用并查集方法,想了很长时间终于想到,如果第di天被占有了那么让di的父节点保存他的前一个节点,然后使用的时候只要查找到一个等于本身的节点就好了,如果查找到0节点那么就是已经被占完了^^
////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 10005;
struct node{int pi, di;}a[maxn];//保存输入
int f[maxn];
bool cmp(node n1, node n2)
{
if(n1.pi != n2.pi)
return n1.pi > n2.pi;
return n1.di < n2.di;
}
int Find(int x)
{
if(f[x] != x)
f[x] = Find(f[x]);
return f[x];
}
int main()
{
int i, N, x;
while(scanf("%d", &N) != EOF)
{
int ans = 0;
for(i=0; i<N; i++)
scanf("%d%d", &a[i].pi, &a[i].di);
for(i=0; i<maxn; i++)//也可以求出最大天数进行初始化
f[i] = i;
sort(a, a+N, cmp);
for(i=0; i<N; i++)
{
x = Find(a[i].di);
if(x != 0)
{
ans += a[i].pi;
f[x] = x-1;
}
}
printf("%d ", ans);
}
return 0;
}
using namespace std;
const int maxn = 10005;
struct node{int pi, di;}a[maxn];//保存输入
int f[maxn];
bool cmp(node n1, node n2)
{
if(n1.pi != n2.pi)
return n1.pi > n2.pi;
return n1.di < n2.di;
}
int Find(int x)
{
if(f[x] != x)
f[x] = Find(f[x]);
return f[x];
}
int main()
{
int i, N, x;
while(scanf("%d", &N) != EOF)
{
int ans = 0;
for(i=0; i<N; i++)
scanf("%d%d", &a[i].pi, &a[i].di);
for(i=0; i<maxn; i++)//也可以求出最大天数进行初始化
f[i] = i;
sort(a, a+N, cmp);
for(i=0; i<N; i++)
{
x = Find(a[i].di);
if(x != 0)
{
ans += a[i].pi;
f[x] = x-1;
}
}
printf("%d ", ans);
}
return 0;
}