最大匹配。
从后往前匹配就可以知道最大的序列。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <iostream>
#define MaxN 100005
#define MaxS 65
using namespace std;
bool checked[MaxN];
int x[MaxS];
int y[MaxN];
int stu;
int max_rank, min_rank;
bool map[MaxS][MaxN];
bool search(int i)
{
for(int j = min_rank; j <= max_rank; j++) {
if(!checked[j] && map[i][j]) {
checked[j] = true;
if(y[j] == -1 || search(y[j])) {
x[i] = j;
y[j] = i;
return true;
}
}
}
return false;
}
int getMatch()
{
int match = 0;
for(int i = 1; i <= stu; i++)
x[i] = -1;
for(int j = min_rank; j <= max_rank; j++)
y[j] = -1;
for(int i = stu; i >= 1; i--) {
if(x[i] == -1) {
memset(checked, false, sizeof(checked));
if(search(i))
match++;
}
}
return match;
}
int main()
{
int t;
while(scanf("%d", &t) != EOF) {
while(t--) {
scanf("%d", &stu);
max_rank = 0;
min_rank = MaxN;
memset(map, false, sizeof(map));
for(int i = 1; i <= stu; i++) {
int a, b;
scanf("%d%d", &a, &b);
max_rank = max(max_rank, max(a, b));
min_rank = min(min_rank, min(a, b));
for(int j = a; j <= b; j++)
map[i][j] = true;
}
int res = getMatch();
printf("%d\n", res);
int count = 0;
for(int i = 1; i <= stu; i++) {
if(x[i] != -1) {
count++;
if(count < res)
printf("%d ", i);
else
printf("%d\n", i);
}
}
}
}
return 0;
}