对于第i个人,我们知道他的合法区间[a[i].x,a[i].y]。首先我们将其和他合法区间内的第一个值进行匹配,如果有后来的人需要和这个值匹配的时候,我们就让这个人和别的合法区间内的值进行匹配,如果匹配成功,就将他之前所匹配的值让出来给后来的人,如果匹配失败,就继续占着这个位置。
要求最大字典序,所以从后往前匹配
#include<cstdio>
#include<cstring>
const int maxn=65;
const int maxm=1e5+7;
int linker[maxm];
int used[maxm];
int n;
int vis[maxn];
int a[maxn],b[maxn];
bool dfs(int u)
{
for(int i=a[u];i<=b[u];i++)
{
int v=i;
if(!used[v])
{
used[v]=1;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
vis[u]=1;
return true;
}
}
}
return false;
}
void hungary()
{
int res=0;
memset(vis,0,sizeof(vis));
memset(linker,-1,sizeof(linker));
for(int u=n;u>=1;u--)
{
memset(used,false,sizeof(used));
if(dfs(u))
res++;
}
printf("%d\n",res);
int flag=0;
for(int i=1;i<=n;i++)
{
if(vis[i])
{
if(flag==0)
{
printf("%d",i);
flag=1;
}
else
printf(" %d",i);
}
}
printf("\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
hungary();
}
}