ZOJ 3953 貪心+優先佇列
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;
}