热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

poj1904

题意:国王有n个儿子,现在有n个美女,每个儿子都有若干个梦中情人,现在已经有一个方案使每个王子都能与自己的梦中情人之一结婚。

题意:国王有n个儿子,现在有n个美女,每个儿子都有若干个梦中情人,现在已经有一个方案使每个王子都能与自己的梦中情人之一结婚。现在要求的是,对于每个儿子能选择的配偶是谁(最终每个儿子都能结成婚)?

分析:这个题的建图方法很特别。为了充分利用条件,即最后给出的那个完美匹配,将每个王子向他的梦中情人作一条有向边,完美匹配方案中,美女向匹配的王子作一条有向边。求出图中的强连通分量,与王子在同一个强连通分量且该王子喜欢的美女就是答案。

正确性:王子集合{x1,x2,......,xn},美女集合{y1,y2,......,yn},假设在原完美匹配方案中每个匹配都是(xi,yi),显然yi是xi的一个选项。假如xi选了yj(j!=i),则原先与yj匹配的王子xj要找另一个女人,yi要与另一个王子匹配,假如xj喜欢yi,那么yj就可以是xi的另一个选项了,假如xj不喜欢yi,那么就继续下去拆散现有的完美匹配,直到有个王子喜欢yi。所以这样就相当于要找一条由xi出发到yi的通路(等价于由xi出发回到xi的回路),只要这样的回路存在,王子就可以与回路中任意一个他喜欢的美女匹配了。这样也就相当于求包含xi的强连通分量。(注意:求出强连通分量之后,只有王子喜欢的美女才能匹配)。

View Code

1 #include
2 #include
3 #include
4 #include
5 using namespace std;
6 stack<int> s;
7 vector<int> arc[5005],group[5005];
8 bool visited[5005],instack[5005],matrix[2001][2001];
9 int counter,low[5005],num[5005],sn,set[5005],n;
10 void tarjan(int u)
11 {
12 int i,v;
13 num[u]&#61;low[u]&#61;&#43;&#43;counter;
14 visited[u]&#61;true;
15 instack[u]&#61;true;
16 s.push(u);
17 for(i&#61;0;i)
18 {
19 v&#61;arc[u][i];
20 if(!visited[v])
21 {
22 tarjan(v);
23 low[u]&#61;min(low[v],low[u]);
24 }
25 else if(instack[v])
26 low[u]&#61;min(low[u],num[v]);
27 }
28 if(num[u]&#61;&#61;low[u])
29 {
30 do
31 {
32 v&#61;s.top();
33 if(v>n)//v is a girl
34 group[sn].push_back(v);
35 else
36 set[v]&#61;sn;
37 instack[v]&#61;false;
38 s.pop();
39 }while(u!&#61;v);
40 sort(group[sn].begin(),group[sn].end());
41 sn&#43;&#43;;
42 }
43 }
44 int main()
45 {
46 while(~scanf("%d",&n))
47 {
48 for(int i&#61;1;i<&#61;n;i&#43;&#43;)
49 {
50 for(int j&#61;1;j<&#61;n;j&#43;&#43;)
51 matrix[i][j]&#61;false;
52 }
53 for(int i&#61;1;i<&#61;n;i&#43;&#43;)
54 {
55 int m;
56 scanf("%d",&m);
57 for(int j&#61;0;j)
58 {
59 int v;
60 scanf("%d",&v);
61 matrix[i][v]&#61;true;
62 arc[i].push_back(v&#43;n);
63 }
64 }
65 for(int i&#61;1;i<&#61;n;i&#43;&#43;)
66 {
67 int u;
68 scanf("%d",&u);
69 arc[u&#43;n].push_back(i);
70 }
71 for(int i&#61;1;i<&#61;2*n;i&#43;&#43;)
72 instack[i]&#61;visited[i]&#61;false;
73 sn&#61;counter&#61;0;
74 for(int i&#61;1;i<&#61;n;i&#43;&#43;)
75 {
76 if(!visited[i])
77 tarjan(i);
78 }
79 for(int i&#61;1;i<&#61;n;i&#43;&#43;)
80 {
81 vector<int> ans;
82 for(int j&#61;0;jset[i]].size();j&#43;&#43;)
83 {
84 if(matrix[i][group[set[i]][j]-n])
85 ans.push_back(group[set[i]][j]-n);
86 }
87 printf("%d",ans.size());
88 for(int j&#61;0;j)
89 printf(" %d",ans[j]);
90 printf("\n");
91 ans.clear();
92 }
93 for(int i&#61;1;i<&#61;2*n;i&#43;&#43;)
94 arc[i].clear();
95 for(int i&#61;0;i)
96 group[i].clear();
97 }
98 return 0;
99 }

 


转载于:https://www.cnblogs.com/ZShogg/archive/2013/03/24/2978513.html


推荐阅读
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了C函数ispunct()的用法及示例代码。ispunct()函数用于检查传递的字符是否是标点符号,如果是标点符号则返回非零值,否则返回零。示例代码演示了如何使用ispunct()函数来判断字符是否为标点符号。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
author-avatar
喵喵方小幺
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有