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种课,给出时间,每种课在星期几的第几节课上 ...
随机推荐
- pta 编程题7 List Leaves
其它pta数据结构编程题请参见:pta 这次的编程作业要求从上到下,从左到右输出一棵树的叶子节点,即树的层序遍历,用队列的方式来实现. 注意enqueue和dequeue函数参数为Queue & ...
- hdu-1532 Drainage Ditches---最大流模板题
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1532 题目大意: 给出有向图以及边的最大容量,求从1到n的最大流 思路: 传送门:最大流的增广路算法 ...
- 转载请注明:Windows 系统必备好用软件&工具合集跟推荐 | 老D博客
Windows 系统必备好用软件&工具合集跟推荐 97 63,371 A+ 所属分类:工具软件 一.浏览器 二.下载软件 三.播放软件 五.电子邮件客户端 六.图片/照片 浏览查看工具 七.文 ...
- Angular6中[ngClass]、[ngStyle]的基本使用
1.ngStyle 基本用法 <div [ngStyle]="{'background-color':'green'}"></<div> 判断添加 & ...
- Java基础面试操作题: 获取 1-20 之间的随机数,共计 20 个,要求不能重复 获取 1-20 之间的随机数,共计 10 个,要求不能重
package com.swift; import java.util.HashSet; import java.util.Random; import java.util.Set; public c ...
- 2018.11.7 Nescafe29 T1 穿越七色虹
题目 题目背景 在 Nescafe27 和 28 中,讲述了一支探险队前往 Nescafe 之塔探险的故事…… 当两位探险队员以最快的时间把礼物放到每个木箱里之后,精灵们变身为一缕缕金带似的光,簇簇光 ...
- 第2 章Python 语言基础
必背必记 1.转义字符 Python 中的字符串还支持转义字符.所谓转义字符是指使用反斜杠“\”对一些特殊字符进行转义. \ 续行符 \n 换行符 \0 空 \t 水平制表符,用于横向跳到下一制表 ...
- keepalived原理(主从配置+haproxy)及配置文件详解
下图描述了使用keepalived+Haproxy主从配置来达到能够针对前段流量进行负载均衡到多台后端web1.web2.web3.img1.img2.但是由于haproxy会存在单点故障问题,因此使 ...
- 整理好的一些mysql表详细操作
一.创建表的完整语法#语法:create table 库名.表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件]);约束条件:是 ...
- Union found
Use array. class UnionFound { public: vector<int> v; int cnt; UnionFound(int n) { v = vector&l ...