题目链接:http://poj.org/problem?id=1904

题意:有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王子可以和几个妹子结婚,按序号升序输出妹子的编号,这个表应满足所有的王子最终都有妹子和他结婚。

分析:很好的图论题,把强连通分量和完美匹配结合起来了,记得多校的时候看到类似的题目(hdu 4685),但是不会做,还以为是二分匹配=_=

首先建图,如果王子u喜欢妹子v,则建一条边u指向v(u,v),对于大臣给出的初始完美匹配,如果王子u和妹子v结婚,则建一条边v指向u(v,u),然后求强连通分量,

对于每个王子和妹子,如果他们都在同一个强连通分量内,则他们可以结婚。

为什么呢?因为每个王子只能和喜欢的妹子结婚,初始完美匹配中的丈夫和妻子之间有两条方向不同的边可以互达,则同一个强连通分量中的王子数和妹子数一定是相等的,若王子x可以和另外的一个妹子a结婚,妹子a的原配王子y肯定能找到另外一个妹子b结婚,因为如果找不到的话,则x和a必不在同一个强连通分量中。

所以一个王子可以和所有与他同一强连通分量的妹子结婚,而这不会导致同一强连通分量中的其他王子找不到妹子结婚。

好像很绕的样子@_@。。。。。大家在纸上画画图吧

建图的时候王子从1~n编号,妹子从n+1~2*n编号

这一题的数据量挺大的,光是输入输出就会消耗很多时间了,可以用输入输出外挂来加速读入和输出。

不加输入外挂9000+ms

加输入外挂8000+ms

加输入输出外挂500+ms

AC代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. const int N=+;
  7. const int M=+;
  8. struct EDGE{
  9. int v,next;
  10. }edge[M];
  11. int first[N],low[N],dfn[N],sta[M],belong[N],ans[N];
  12. bool instack[N];
  13. int g,cnt,top,scc;
  14.  
  15. void AddEdge(int u,int v)
  16. {
  17. edge[g].v=v;
  18. edge[g].next=first[u];
  19. first[u]=g++;
  20. }
  21. int min(int a,int b)
  22. {
  23. return a<b?a:b;
  24. }
  25. void Tarjan(int u) //求强连通分量
  26. {
  27. int i,v;
  28. low[u]=dfn[u]=++cnt;
  29. sta[++top]=u;
  30. instack[u]=true;
  31. for(i=first[u];i!=-;i=edge[i].next)
  32. {
  33. v=edge[i].v;
  34. if(!dfn[v])
  35. {
  36. Tarjan(v);
  37. low[u]=min(low[u],low[v]);
  38. }
  39. else if(instack[v])
  40. low[u]=min(low[u],dfn[v]);
  41. }
  42. if(low[u]==dfn[u])
  43. {
  44. scc++;
  45. while()
  46. {
  47. v=sta[top--];
  48. instack[v]=false;
  49. belong[v]=scc; //缩点
  50. if(u==v)
  51. break;
  52. }
  53. }
  54. }
  55. int Scan() //输入外挂
  56. {
  57. int res=,ch,flag=;
  58. if((ch=getchar())=='-')
  59. flag=;
  60. else if(ch>=''&&ch<='')
  61. res=ch-'';
  62. while((ch=getchar())>=''&&ch<='')
  63. res=res*+ch-'';
  64. return flag?-res:res;
  65. }
  66. void Out(int a) //输出外挂
  67. {
  68. if(a>)
  69. Out(a/);
  70. putchar(a%+'');
  71. }
  72. int main()
  73. {
  74. int n,i,u,v,k;
  75. while(scanf("%d",&n)!=EOF)
  76. {
  77. g=cnt=top=scc=;
  78. memset(first,-,sizeof(first));
  79. memset(dfn,,sizeof(dfn));
  80. memset(instack,false,sizeof(instack));
  81. for(i=;i<=n;i++)
  82. {
  83. // scanf("%d",&k);
  84. k=Scan();
  85. while(k--)
  86. {
  87. // scanf("%d",&v);
  88. v=Scan();
  89. AddEdge(i,v+n); //王子i喜欢妹子v
  90. }
  91. }
  92. for(i=;i<=n;i++)
  93. {
  94. // scanf("%d",&v);
  95. v=Scan();
  96. AddEdge(v+n,i); //王子i可以和妹子v结婚
  97. }
  98.  
  99. for(i=;i<=*n;i++) //求强连通分量
  100. if(!dfn[i])
  101. Tarjan(i);
  102.  
  103. for(u=;u<=n;u++)
  104. {
  105. int count=;
  106. for(i=first[u];i!=-;i=edge[i].next)
  107. {
  108. v=edge[i].v;
  109. if(belong[u]==belong[v]) //同一个强连通分量
  110. ans[count++]=v-n;
  111. }
  112. sort(ans,ans+count);
  113. // printf("%d",count);
  114. Out(count);
  115. for(i=;i<count;i++)
  116. {
  117. //printf(" %d",ans[i]);
  118. putchar(' ');
  119. Out(ans[i]);
  120. }
  121. // printf("\n");
  122. putchar('\n');
  123. }
  124. }
  125. return ;
  126. }

poj 1904(强连通分量+输入输出外挂)的更多相关文章

  1. poj 1904(强连通分量+完美匹配)

    传送门:Problem 1904 https://www.cnblogs.com/violet-acmer/p/9739990.html 参考资料: [1]:http://www.cnblogs.co ...

  2. poj 1904 强连通分量

    思路:先有每个儿子向所有他喜欢的姑娘建边,对于最后给出的正确匹配,我们建由姑娘到相应王子的边.和某个王子在同一强连通分量,且王子喜欢的姑娘都是该王子能娶得.思想类似匈牙利算法求匹配的时候,总能找到增广 ...

  3. poj 2186 强连通分量

    poj 2186 强连通分量 传送门 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 33414 Acc ...

  4. POJ 1904 King's Quest 强联通分量+输入输出外挂

    题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...

  5. poj 2762(强连通分量+拓扑排序)

    题目链接:http://poj.org/problem?id=2762 题意:给出一个有向图,判断任意的两个顶点(u,v)能否从u到达v,或v到达u,即单连通,输出Yes或No. 分析:对于同一个强连 ...

  6. poj 1236(强连通分量分解模板题)

    传送门 题意: N(2<N<100)个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输. 问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都 ...

  7. POJ(2186)强连通分量分解

    #include<cstdio> #include<vector> #include<cstring> using namespace std; ; vector& ...

  8. Popular Cows POJ - 2186(强连通分量)

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10, ...

  9. Poj 1904 King's Quest 强连通分量

    题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...

随机推荐

  1. 我是怎样和Linux系统结缘并通过红帽RHCE认证的

    我高考完当时就是选择的计算机科学与技术专业,上大学以后联想到的和计算机相关的就只有写代码,开发,网站,网页设计,就没有其他的了,当时学习写代码也都是在Windows上,什么C#.C++之类的?大约在大 ...

  2. WebSocket原理与实践(一)---基本原理

    WebSocket原理与实践(一)---基本原理 一:为什么要使用WebSocket?1. 了解现有的HTTP的架构模式:Http是客户端/服务器模式中请求-响应所用的协议,在这种模式中,客户端(一般 ...

  3. AliOS-Things linkkitapp解读

    app-example-linkkitapp是AliOS-Things提供的设备联网并且和阿里云IOT平台数据交互的一个示例程序: 1:application_start()程序在app_entry. ...

  4. BSGS-Junior·大步小步算法

    本文原载于:http://www.orchidany.cf/2019/02/06/BSGS-junior/#more \(\rm{0x01}\) \(\mathcal{Preface}\) \(\rm ...

  5. spring HibernateTemplate.save() 方法的自动提交问题

    如题: service1: dao1.save(obj);   //失败,应该给spring捕获,但没有,程序继续执行下去了. redisService.fun1();  //被执行 service2 ...

  6. 利用git向github上远程提交一个自己的开源项目

    1.在电脑的系统变量中的path路径中配置git的环境变量: 找到git安装路径中bin的位置,如:X:\Git\bin 找到git安装路径中git-core的位置,如:X:\Git\libexec\ ...

  7. ImageView android:scaleType="centerCrop"

    转载地址:http://www.cnblogs.com/yejiurui/archive/2013/02/25/2931767.html 在网上查了好多资料,大致都雷同,大家都是互相抄袭的,看着很费劲 ...

  8. [01] 浅谈RESTful风格的API

    1.什么是RESTful风格的API REST,即Representational State Transfer,可以理解为"(资源的)表现层状态转化". 在网络上,我们通过浏览器 ...

  9. Ubuntu16.04中搭建TFTP 和 NFS 服务器

    Ubuntu 16.04中搭建TFTP服务 1. 安装 $ apt-get install tftp-hpa tftpd-hpa   2. 建立目录 $ mkdir /tftpboot # 这是建立t ...

  10. Ajax获取 Json文件提取数据

    摘自 Ajax获取 Json文件提取数据 1. json文件内容(item.json) [ { "name":"张国立", "sex":&q ...