题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3729
题意:
给定 n个学生 说的 自己 考试排名的 可能范围
确定最多几个人说真话
如果有多种答案,输出字典序最大的那种
这里字典序最大我们直接修改下二分匹配的匹配顺序即可
解法:
题目给定 点 映射到 数轴的区间 上, 问最多多少点可以成功映射到数轴上
很显然 点就是 x集 , 整个数轴 就是 y集 , 点对应的整个区间就是映射的边 ,所以直接有了一个二分图
//HDU 3729
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
const int maxm = 65;
struct node{
int x, y;
}E[maxm];
int n;
int match[maxm], Link[maxn];
bool vis[maxn];
bool dfs(int x){
for(int i = E[x].x; i <= E[x].y; i++){
if(!vis[i]){
vis[i] = 1;
if(Link[i] == -1 || dfs(Link[i])){
Link[i] = x;
match[x] = i;
return true;
}
}
}
return false;
}
int work(){
memset(Link, -1, sizeof(Link));
memset(match, -1, sizeof(match));
int ans = 0;
for(int i = n-1; i >= 0; i--){
memset(vis, 0, sizeof(vis));
ans += dfs(i);
}
return ans;
}
int main(){
int T; scanf("%d", &T);
while(T--){
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d%d", &E[i].x, &E[i].y);
}
int ans = work();
printf("%d\n", ans);
for(int i = 0; i < n; i++){
if(match[i]!=-1){
ans--;
printf("%d", i+1);
if(ans) printf(" ");
else printf("\n");
}
}
}
return 0;
}