acm.hdu.edu.cn/showproblem.php?pid=3729
要求输出字典序最大的那个结果 所以逆向进行二分匹配。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
int n,l,r,G[61][100010],t[61],cnt;
int check[100010],ma[61],mb[100010];
int DFS(int u){
for(int i=l; i<=r; i++){
if(!check[i] && G[u][i] > 0){
check[i] = 1;
if(mb[i] == -1 || DFS(mb[i])){
ma[u] = i;
mb[i] = u;
return 1;
}
}
}
return 0;
}
int MMC(){
int res = 0;
memset(ma,-1,sizeof(ma));
memset(mb,-1,sizeof(mb));
for(int i=n; i>=1; i--){
memset(check, 0, sizeof(check));
res += DFS(i);
}
return res;
}
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
scanf("%d",&n);
l = 1e9, r = -1;
memset(G, 0, sizeof(G));
for(int i=1; i<=n; i++){
int a,b;
scanf("%d%d",&a,&b);
for(int j=a; j<=b; j++){
G[i][j] = 1;
r = max(r, j);
l = min(l, j);
}
}
int ans = MMC(); printf("%d\n",ans);
cnt = 0;
for(int i=l; i<=r; i++)
if(mb[i] != -1)
t[cnt++] = mb[i];
sort(t, t + cnt);
cout << t[0];
for(int i=1; i<cnt; i++)
cout << " " << t[i];
cout << endl;
}
return 0;
}