ZOJ 3953 Intervals

来源:互联网 发布:15年nba总决赛个人数据 编辑:程序博客网 时间:2024/05/16 18:15

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 aintersects with bb intersects with c and c intersects 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 m equals to 0, you should output an empty line in the second line.

Sample Input
1112 54 73 96 111 1210 158 1713 1816 2014 2119 22
Sample Output
4

3 5 7 10

题意:删除最少的区间使得三个区间存在一个不相交的两个区间。

思路:三个里面只有两个两两相交,如果三个两两相交就删除右端点最大的边

代码:

#include <iostream>#include<stdio.h>#include<cstdio>#include<iostream>#include<algorithm>#include<math.h>#include<string.h>#include<map>#include<queue>#include<vector>#include<deque>#define ll long long#define inf 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a))using namespace std;struct node{    int l,r,id;} a[50005],b[11];bool cmp(node a,node b){    if(a.l==b.l)        return a.r<b.r;    return a.l<b.l;}bool cmp1(node a,node b){    return a.r>b.r;}bool fun(node a,node b,node c){    return b.l<=a.r&&c.l<=a.r&&c.l<=b.r;}int bb[50005];int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n,k=0;        scanf("%d",&n);        mem(bb,0);        for(int i=1; i<=n; i++)        {            scanf("%d%d",&a[i].l,&a[i].r);            a[i].id=i;        }        sort(a+1,a+n+1,cmp);//        for(int i=1; i<=n; i++)//        {//            printf("@%d %d\n",a[i].l,a[i].r);//        }        b[0]=a[1];        b[1]=a[2];        for(int i=3; i<=n; i++)        {            b[2]=a[i];            sort(b,b+3,cmp);//            printf("#%d %d\n",b[0].l,b[0].r);//            printf("##%d %d\n",b[1].l,b[1].r);//            printf("###%d %d\n",b[2].l,b[2].r);            if(fun(b[0],b[1],b[2]))            {                //printf("##\n");                sort(b,b+3,cmp1);                bb[k++]=b[0].id;                b[0]=b[2];//删除最大的那条边,存在b【2】中下一次会被替换                //b[1]=b[1];            }            else            {               sort(b,b+3,cmp1);//删除第一个区间,更新            }        }        printf("%d\n",k);        sort(bb,bb+k);        for(int i=0; i<k; i++)        {            printf("%d ",bb[i]);        }        printf("\n");    }}


0 0