HDU 3729 二分匹配 反向匹配
题意:
给定 n个学生 说的 自己 考试排名的 可能范围
确定最多几个人说真话
如果有多种答案,输出字典序最大的那种( 要求字典序最大,所以solve中从最大字典序开始匹配)
思路:
题目给定 点 映射到 数轴的区间 上, 问最多多少点可以成功映射到数轴上
很显然 点就是 x集 , 整个数轴 就是 y集 , 点对应的整个区间就是映射的边 ,所以直接有了一个二分图
#include<iostream>#include<string.h>#include<stdio.h>using namespace std;#define N 100100#define M 65struct node{int x,y;}len[M];int n;int lef[N],match[M];bool vis[N];bool dfs(int x){for(int i=len[x].x; i<= len[x].y; i++){if(!vis[i]){vis[i] = true;if(lef[i] == -1 || dfs(lef[i])){lef[i] = x;match[x] = i;return true;}}}return false;}int solve(){memset(lef, -1, sizeof(lef));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 i,T;scanf("%d",&T);while(T--){scanf("%d",&n);for(i=0;i<n;i++)scanf("%d %d",&len[i].x,&len[i].y);int ans = solve();printf("%d\n",ans);for(i=0;i<n;i++)if(match[i] != -1){ans--;printf("%d",i+1);if(ans)printf(" ");else printf("\n");}}return 0;}