题目链接: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;
}