原题:http://acm.hdu.edu.cn/showproblem.php?pid=3729
题意:
给出n个学生说的自己的考试排名范围;
问最多有几个人说真话,并且输出字典序最大的一种(所以匹配时从n-1开始);
思路:
将学生作为X集,整个数轴作为y集,映射就是点和对应区间的每一个数;
然后反向求最大匹配;
#include<stdio.h>
#include<string.h>
const int maxn = 100;
const int maxm = 100005;
int lef[maxm], link[maxn];
bool T[maxm];
int n;
struct node
{
int x, y;
}s[maxn];
bool match(int k)
{
for(int i = s[k].x;i<=s[k].y;i++)
{
if(!T[i])
{
T[i] = true;
if(lef[i] == -1 || match( lef[i] ))
{
lef[i] = k;
link[k] = i;
return true;
}
}
}
return false;
}
int solve()
{
memset(lef, -1, sizeof(lef));
memset(link, -1, sizeof(link));
int ans = 0;
for(int i = n-1;i>=0;i--)
{
memset(T, 0, sizeof(T));
if( match(i) )
ans++;
}
return ans;
}
int main()
{
int cas;
scanf("%d", &cas);
while(cas--)
{
scanf("%d", &n);
for(int i = 0;i<n;i++)
scanf("%d%d", &s[i].x, &s[i].y);
int ans = solve();
printf("%d\n", ans);
for(int i = 0;i<n;i++)
{
if(link[i]!=-1)
{
ans--;
printf("%d", i+1);
if(ans)
printf(" ");
else
printf("\n");
}
}
}
return 0;
}