您的位置:首页 > 其它

ZOJ 3953 贪心+优先队列

2017-04-10 12:27 459 查看
Intervals
Time Limit: 1 Second      Memory Limit: 65536 KB      Special Judge

Chiaki has n intervals and the i-th of them is [li, ri].
She wants to delete some intervals so that there does not exist three intervals a, b and c such that a intersects with b, b intersects with c and cintersects with a.
Chiaki is interested in the minimum number of intervals which need to be deleted.
Note that interval a intersects with interval b if there exists a real number x such that la ≤ x ≤ ra and lb ≤ x ≤ rb.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 50000) -- the number of intervals.
Each of the following n lines contains two integers li and ri (1 ≤ li < ri ≤
109) denoting the i-th interval. Note that for every 1 ≤ i < j ≤ n, li ≠ lj or ri ≠ rj.
It is guaranteed that the sum of all n does not exceed 500000.

Output

For each test case, output an integer m denoting the minimum number of deletions. Then in the next line, output m integers in increasing order denoting the index
of the intervals to be deleted. If mequals to 0, you should output an empty line in the second line.

Sample Input

1
11
2 5
4 7
3 9
6 11
1 12
10 15
8 17
13 18
16 20
14 21
19 22

Sample Output

4
3 5 7 10


题意:给出n个区间,求至少删掉多少个区间使得不存在区间a, b, c 两两相交

(定义两个区间相交是,区间[l1, r1]和区间[l2, r2]相交,当且仅当存在一个数x,l1<=x<=r1 且 l2<=x<=r2)

题解:先离散化一下  然后对于每个点  先把起点在这个点的线段扔到优先队列里面

如果当前点被二个以上的线段覆盖  就把y最远的那条线段拿出来删掉

用mix记录当前点被多少线段覆盖  dd数组代表每条线段在哪里结束

具体细节请读者自行思考

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
int dd[100005],num[100005],cnt;
struct node{
int x,y,lab;
bool operator <(const node& a)const{
return y<a.y;
}
}e[50005];
vector<int>ans;
priority_queue<node,vector<node>,less<node> >sp;
bool cmp(node a,node b){
return a.x<b.x;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,i,j;
scanf("%d",&n);
memset(dd,0,sizeof(dd));
cnt=0;
for(i=1;i<=n;i++){
scanf("%d%d",&e[i].x,&e[i].y);
e[i].lab=i;
num[++cnt]=e[i].x;
num[++cnt]=e[i].y;
}
sort(e+1,e+1+n,cmp);
int mix=0;
sort(num+1,num+1+cnt);
cnt=unique(num+1,num+1+cnt)-num-1;
for(i=1;i<=n;i++){
e[i].x=lower_bound(num+1,num+1+cnt,e[i].x)-num;
e[i].y=lower_bound(num+1,num+1+cnt,e[i].y)-num;
}
e[n+1].x=-111;
int now=1;
while(!sp.empty())sp.pop();
ans.clear();
for(i=1;i<=cnt;i++){
while(e[now].x==i){
sp.push(e[now]);
mix++;
dd[e[now].y+1]--;
now++;
}
mix+=dd[i];
while(mix>=3){
node f=sp.top();
sp.pop();
mix--;
dd[f.y+1]++;
ans.push_back(f.lab);
}
}
sort(ans.begin(),ans.end());
int dt=ans.size();
printf("%d\n",dt);
for(i=0;i<dt;i++){
printf("%d",ans[i]);
if(i==dt-1)break;
else printf(" ");
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: