您的位置:首页 > 其它

hdu 5360 贪心+优先队列

2015-08-06 21:39 417 查看
贪心的思路还是比较好想的,每次选择cur(已经邀请成功的人数)所在的区间中右端点最小的(因为右端点大的在后面可以邀请成功的几率大),然后很自然的想到可以用一个优先队列来维护这些区间,只要每次把左端点小于等于cur的区间放到优先队列中即可。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

const int N = 100001;
bool visit
;
int a
;

struct Node
{
int r, id;
Node(){}
Node( int _r, int _id )
{
r = _r, id = _id;
}
bool operator < ( const Node & o ) const
{
return r > o.r;
}
};

vector<Node> v
;
priority_queue<Node> q;

int main ()
{
int t;
scanf("%d", &t);
while ( t-- )
{
int n;
scanf("%d", &n);
for ( int i = 0; i <= n; i++ )
{
v[i].clear();
}
for ( int i = 1; i <= n; i++ )
{
scanf("%d", a + i);
}
for ( int i = 1; i <= n; i++ )
{
int tmp;
scanf("%d", &tmp);
v[a[i]].push_back( Node( tmp, i ) );
}
memset( visit, 0, sizeof(visit) );
int cur = 0, cnt = 1;
while ( 1 )
{
for ( int i = 0; i < v[cur].size(); i++ )
{
q.push(v[cur][i]);
}
bool flag = false;
while ( !q.empty() )
{
Node tt = q.top();
q.pop();
a[cnt++] = tt.id;
visit[tt.id] = true;
if ( tt.r >= cur )
{
cur++;
flag = true;
break;
}
}
if ( !flag )
{
break;
}
}
for ( int i = 1; i <= n; i++ )
{
if ( !visit[i] )
{
a[cnt++] = i;
}
}
printf("%d\n", cur);
for ( int i = 1; i < n; i++ )
{
printf("%d ", a[i]);
}
printf("%d\n", a
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: