1. 程式人生 > >ZOJ 3953 貪心+優先佇列

ZOJ 3953 貪心+優先佇列

Intervals
Time Limit: 1 Second      Memory Limit: 65536 KB      Special Judge

Chiaki has n intervals and the i-th of them is [liri]. She wants to delete some intervals so that there does not exist three intervals ab and c such that a intersects with bb 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 ≤ nli ≠ 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;
}