HDU 3729 I'm Telling the Truth (最小路径覆盖=顶点数-最大匹配数)
2013-09-02 19:36
375 查看
I'm Telling the Truth
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1050 Accepted Submission(s): 520
[align=left]Problem Description[/align]
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 5004th and 5005th, Student2 said he was between 5005th and 5006th, Student3 said he was between 5004th and 5006th, Student4
said he was between 5004th and 5006th, 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.
[align=left]Input[/align]
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 (n <= 60) 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 Xiand Yi, inclusive.
[align=left]Output[/align]
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)
[align=left]Sample Input[/align]
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
[align=left]Sample Output[/align]
3
2 3 4
5
1 3 5 6 7
题意:有n个学生,每个学生给出他的成绩所在的区间。输出最多有多少个学生说真话,并且按字典序输出说真话的学生编号,若有多种情况,则输出字典序最大的。
思路:二分图的最大匹配。将学生与成绩进行匹配。由于要求输出字典序最大的序列,我们可以从学生n开始匹配,这样就会使学生编号大的先匹配。
最小路径覆盖=顶点数-最大匹配数
import java.io.*; import java.util.*; public class Main { int t,n; int MAX=100010; int link[]=new int[MAX]; int map[]=new int[MAX]; boolean[] mark=new boolean[MAX]; Node node[]; public static void main(String[] args) { new Main().work(); } void work(){ Scanner sc=new Scanner(new BufferedInputStream(System.in)); t=sc.nextInt(); while(t--!=0){ n=sc.nextInt(); node=new Node[n+1]; for(int i=1;i<=n;i++){ int min=sc.nextInt(); int max=sc.nextInt(); node[i]=new Node(min,max); } hungary(); } } //匈牙利算法 void hungary(){ Arrays.fill(link,0); Arrays.fill(map,0); int ans=0; for(int i=n;i>=1;i--){ Arrays.fill(mark,false); if(DFS(i)) map[ans++]=i; } //输出 System.out.println(ans); for(int i=ans-1;i>=0;i--){ System.out.print(map[i]); if(i!=0) System.out.print(" "); } System.out.println(); } boolean DFS(int x){ for(int i=node[x].min;i<=node[x].max;i++){ if(!mark[i]){ mark[i]=true; if(link[i]==0||DFS(link[i])){ link[i]=x; return true; } } } return false; } class Node{ int min; int max; Node(int min,int max){ this.min=min; this.max=max; } } }
相关文章推荐
- HDU 1151 Air Raid(最小路径覆盖 = 顶点数 - 最大匹配数)
- HDU 4160 Dolls (最小路径覆盖=顶点数-最大匹配数)
- POJ 3020 最小路径覆盖 = 顶点数-最大匹配数 二分匹配
- HDOJ---1151 Air Raid[匈牙利算法:最小路径覆盖数=原图顶点数–二分图最大匹配数]
- HDU 4160 最小路径覆盖 = 顶点数 - 最大匹配数 二分匹配
- poj1422 Air Raid 最小路径覆盖=顶点数-最大匹配数
- poj2060 Taxi Cab Scheme 最小路径覆盖=顶点数-最大匹配数
- 匈牙利算法 hdu 1151有向图的最小路径覆盖=顶点数-最大匹配数
- 最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)
- poj3020_最小覆盖路径(顶点个数-二分图最大匹配数)
- 最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)
- 最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)
- poj3020 匈牙利算法+公式:二分无向图的最小路径覆盖 = 顶点数 - 最大二分匹配数 / 2
- HDU 4160 Dolls (最小路径覆盖=顶点数-最大匹配数)
- poj2594 Treasure Exploration 最小路径覆盖=顶点数-最大匹配数
- poj2594-Treasure Exploration(最小路径覆盖,最大匹配,floyed(优化))
- poj 1422 Air Raid 有向无环图最小路径覆盖=N-最大匹配
- 【POJ3020】【总数-最大二分匹配】【最小路径覆盖和点覆盖的区别是 路径的话要所有点覆盖了】
- DAG的最小路径覆盖和二分图的最大匹配
- 二分图最大匹配,点的最小覆盖,最小路径覆盖