UVALive 5033 I'm Telling the Truth 二分图最大匹配(略有修改)
Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu
Description
After this year's college-entrance exam, the teacher did a survey in his class on students' score. There are n students in the class. The students didn't want to tell their teacher their exact score; they only told their teacher their rank in the province (in the form of intervals).
After asking all the students, the teacher found that some students didn't tell the truth. For example, Student1 said he was between 5004-th and 5005-th, Student2 said he was between 5005-th and 5006-th, Student3 said he was between 5004-th and 5006-th, Student4 said he was between 5004-th and 5006-th, too. This situation is obviously impossible. So at least one told a lie. Because the teacher thinks most of his students are honest, he wants to know how many students told the truth at most.
Input
There is an integer in the first line, represents the number of cases (at most 100 cases). In the first line of every case, an integer n(n60) represents the number of students. In the next n lines of every case, there are 2 numbers in each line, Xi and Yi(1
Xi
Yi
100000), means the i-th student's rank is between Xi and Yi, inclusive.
Output
Output 2 lines for every case. Output a single number in the first line, which means the number of students who told the truth at most. In the second line, output the students who tell the truth, separated by a space. Please note that there are no spaces at the head or tail of each line. If there are more than one way, output the list with maximum lexicographic. (In the example above, 1 2 3;1 2 4;1 3 4;2 3 4 are all OK, and 2 3 4 with maximum lexicographic)
Sample Input
2
4
5004 5005
5005 5006
5004 5006
5004 5006
7
4 5
2 3
1 2
2 2
4 4
2 3
3 4
Sample Output
3
2 3 4
5
1 3 5 6 7
好爽!
我在百度搜索hdu 二分图最大匹配,百度给出的第一个结果就是这道题。刚开始看这道题的时候,以我对二分图匹配非常浅薄的理解,我怎么也想不明白这道题怎么就二分图最大匹配了。
后来想明白了,对于第i个人,我们知道他的合法区间[a[i].x,a[i].y]。首先我们将其和他合法区间内的第一个值进行匹配,如果有后来的 人需要和这个值匹配的时候,我们就让这个人和别的合法区间内的值进行匹配,如果匹配成功,就将他之前所匹配的值让出来给后来的人,如果匹配失败,就继续占 着这个位置。
这里很重要的一点是,对于一个值的匹配,我们遵守先来后到的原则,对于先来的已经匹配成功的人,如果没有找到其他符合条件的位置,这个人占的位置是绝对不能让出来的。这点很关键,因为题目还要求输出所有可能性中字典序最大的。
感觉做完这道题对二分图最大匹配理解深刻了好多,之前就是看懂了模板而已。而且还是1A。爽!
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = ;
const int INF = ;
bool vis[maxn]; //查询右集合中的点有没有被访问过
int link[maxn]; //link[i]表示右集合中的i点是由左集合中的哪个点连接的
int G[][maxn]; //邻接矩阵
int x_cnt;
int y_cnt; //左右集合的点的个数
int a[];
int tmin,tmax;
bool find(int u) //用来寻找增广路 {
for(int i = tmin; i <= tmax; i++) //遍历右集合中的每个点
{
if(!vis[i] && G[u][i]) //没有被访问过并且和u点有边相连
{
vis[i] = true; //标记该点
if(link[i] == - || find(link[i]))
{
//该点是增广路的末端或者是通过这个点可以找到一条增广路
link[i] = u;//更新增广路 奇偶倒置
return true;//表示找到一条增广路
}
}
}
return false;//如果查找了右集合里的所有点还没找到通过该点出发的增广路,该点变不存在增广路
} int solve()
{
int num = ;
memset(link, -, sizeof(link));//初始化为-1表示 不与左集合中的任何元素有link
for(int i =x_cnt ; i >=; i--) //遍历左集合
{
memset(vis, false, sizeof(vis));//每一次都需要清除标记
if(find(i))
num++;//找到一条增广路便num++
}
return num;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
tmin=,tmax=-;
int u,v;
x_cnt=n;
memset(G,,sizeof(G));
for(int i=;i<=n;i++){
scanf("%d%d",&u,&v);
if(u<tmin)
tmin=u;
if(v>tmax){
tmax=v;
}
for(int j=u;j<=v;j++)
G[i][j]=;
}
int cnt=;
int ans=solve();
printf("%d\n",ans);
memset(a,,sizeof(a));
for(int i=tmin;i<=tmax;i++){
if(link[i]!=-)
a[cnt++]=link[i];
}
sort(a,a+cnt); for(int i=;i<cnt;i++){
printf("%d%c",a[i],i==cnt-?'\n':' ');
} }
return ;
}
UVALive 5033 I'm Telling the Truth 二分图最大匹配(略有修改)的更多相关文章
- I'm Telling the Truth(二分图)
.I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- HDU 3729 I'm Telling the Truth(二部图最大匹配+结果输出)
职务地址:HDU 3729 二分图最大匹配+按字典序输出结果. 仅仅要从数字大的開始匹配就能够保证字典序最大了.群里有人问. . 就顺手写了这题. . 代码例如以下: #include <ios ...
- hdu 3729 I'm Telling the Truth 二分图匹配
裸的二分图匹配.需要输出方案. #include<cstdio> #include<cstring> #include<vector> #include<al ...
- hdu3729 I'm Telling the Truth (二分图的最大匹配)
http://acm.hdu.edu.cn/showproblem.php?pid=3729 I'm Telling the Truth Time Limit: 2000/1000 MS (Java/ ...
- hdu 3729 I'm Telling the Truth(二分匹配_ 匈牙利算法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3729 I'm Telling the Truth Time Limit: 2000/1000 MS ( ...
- hdu 3729(二分图最大匹配)
I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- POJ 2226二分图最大匹配
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图 ...
- POJ2239 Selecting Courses(二分图最大匹配)
题目链接 N节课,每节课在一个星期中的某一节,求最多能选几节课 好吧,想了半天没想出来,最后看了题解是二分图最大匹配,好弱 建图: 每节课 与 时间有一条边 #include <iostream ...
- poj 2239 二分图最大匹配,基础题
1.poj 2239 Selecting Courses 二分图最大匹配问题 2.总结:看到一个题解,直接用三维数组做的,很巧妙,很暴力.. 题意:N种课,给出时间,每种课在星期几的第几节课上 ...
随机推荐
- StackOverflow之旅<1>------{去掉烦人的"!=null"判断}
问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc(); } 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何 ...
- LigerUi中表(Grid)控件的相关属性笔记
http://blog.csdn.net/dxnn520/article/details/8216560 // ========================================= [每 ...
- SQL Server中通用数据库角色权限的处理详解
SQL Server中通用数据库角色权限的处理详解 前言 安全性是所有数据库管理系统的一个重要特征.理解安全性问题是理解数据库管理系统安全性机制的前提. 最近和同事在做数据库权限清理的事情,主要是删除 ...
- Fight Against Traffic -简单dijkstra算法使用
题目链接 http://codeforces.com/contest/954/problem/D 题目大意 n m s t 分别为点的个数, 边的个数,以及两个特殊的点 要求s与t间的距离在新增一条边 ...
- 前端JS转图片为base64并压缩、调整尺寸脚本
image to base64 to blob //////////////////////////////////////////////////////////////////////////// ...
- 常见react面试题汇总
已经开源 地址:https://github.com/nanhupatar...关注我们团队: React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加 ...
- JZOJ 5849 d
Description Input Output Data Constraint 做法:考虑贪心使得mina*minb最大,先以a为关键字排序,然后枚举删除最小的0~m个ai,对应删除最小的bi,然后 ...
- Ubuntu12.04下YouCompleteMe安装教程(部分)
1.通过源码编译安装VIM 开发中使用的是Ubuntu 12.04 LTS,通过sudo apt-get install vim安装的版本较低,不支持YCM,所以,用源码编译并安装最新的Vim. 卸载 ...
- python编写登录接口
要求: 输入用户名密码 认证成功显示欢迎信息 输错三次以后锁定 代码如下: # Author:YKwhile(True): select=input('请问是注册还是登录') if selec ...
- HDU - 5017 Ellipsoid(模拟退火)
题意 给一个三维椭球面,求球面上距离原点最近的点.输出这个距离. 题解 模拟退火. 把\(z = f(x, y)\)函数写出来,这样通过随机抖动\(x\)和\(y\)坐标就能求出\(z\). 代码 / ...