题意:有N个王子M个公主,王子喜欢一些公主,而且只能是王子喜欢的人,他们才可以结婚,现在让他们尽可能多的结婚的前提下找出来每个王子都可以和谁结婚。
分析:先求出来他们的最大匹配,因为给的数据未必是完备匹配,所以需要添加一些点使他们成为完备匹配才能求出来的环是完整的,比如第二组数据:

1 2  

2 1 2
如果不添加虚拟点做成匹配,只会匹配成功一个,这样就找不出来环了,所以需要添加虚拟的王子和公主,虚拟的王子喜欢所有的公主,虚拟的公主被所有的王子喜欢,注意都是王子喜欢公主的,公主没有选择喜欢的权利(确实有点悲哀- -)
*************************************************************************
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<vector>
  4. #include<algorithm>
  5. using namespace std;
  6.  
  7. const int MAXN = ;
  8. const int Base = ;
  9. ///base 王子的编号从1开始 公主的编号从base+1开始, 虚拟点的编号从base*2+1开始
  10. int N, M;
  11. bool love[][];
  12. vector< vector <int> >ans;
  13. /***************邻接表*********************/
  14. struct Edge{int v, next;}e[MAXN*MAXN];
  15. int Head[MAXN], cnt;
  16.  
  17. void AddEdge(int u, int v)
  18. {
  19.     e[cnt].= v;
  20.     e[cnt].next = Head[u];
  21.     Head[u] = cnt++;
  22. }
  23. /**************Tarjan**********************/
  24. int dfn[MAXN], low[MAXN], Index;
  25. int Stack[MAXN], instack[MAXN], top;
  26. int belong[MAXN], bnt;
  27.  
  28. void Tarjan(int i)
  29. {
  30.     int v;
  31.  
  32.     dfn[i] = low[i] = ++Index;
  33.     Stack[++top] = i, instack[i] = true;
  34.  
  35.     for(int j=Head[i]; j!=-; j=e[j].next)
  36.     {
  37.         v = e[j].v;
  38.  
  39.         if( !dfn[v] )
  40.         {
  41.             Tarjan(v);
  42.             low[i] = min(low[i], low[v]);
  43.         }
  44.         else if( instack[v] )
  45.             low[i] = min(low[i], dfn[v]);
  46.     }
  47.  
  48.     if(low[i] == dfn[i])
  49.     {
  50.         ++bnt;
  51.         do
  52.         {
  53.             v = Stack[top--];
  54.             instack[v] = false;
  55.             belong[v] = bnt;
  56.             if(> Base)
  57.                 ans[bnt].push_back(v-Base);
  58.         }
  59.         while(!= v);
  60.     }
  61. }
  62. /***************匈牙利********************/
  63. int Lx[MAXN], Ly[MAXN];
  64. bool used[MAXN];
  65.  
  66. bool Find(int i)
  67. {
  68.     for(int j=Head[i]; j!=-; j=e[j].next)
  69.     {
  70.         int v = e[j].v;
  71.  
  72.         if( !used[v] )
  73.         {
  74.             used[v] = true;
  75.             if( !Ly[v] || Find(Ly[v]) )
  76.             {
  77.                 Ly[v] = i;
  78.                 Lx[i] = v;
  79.  
  80.                 return true;
  81.             }
  82.         }
  83.     }
  84.  
  85.     return false;
  86. }
  87. void XYL()///顺便添加虚拟点
  88. {
  89.     int i, j, k, sum=;
  90.  
  91.     for(i=; i<=N; i++)
  92.     {
  93.         memset(used, false, sizeof(used));
  94.         sum += Find(i);
  95.     }
  96.  
  97.     k = Base *  + ;///虚拟点开开始处
  98.  
  99.     for(i=; i<=N; i++)
  100.     {///遍历王子部分,看那个王子没有匹配,为他虚拟一个公主,这个公主所有的王子都喜欢
  101.         if(Lx[i] == false)
  102.         {
  103.             Lx[i] = k;
  104.             Ly[k] = i;
  105.  
  106.             for(j=; j<=N; j++)
  107.                 AddEdge(j, k);
  108.             k++;
  109.         }
  110.     }
  111.  
  112.     for(i=Base+; i<=Base+M; i++)
  113.     {///遍历公主部分,看哪个公主没有匹配,为她虚拟一个王子,这个王子喜欢所有的公主
  114.         if(Ly[i] == false)
  115.         {
  116.             Lx[k] = i;
  117.             Ly[i] = k;
  118.  
  119.             for(j=Base+; j<=Base+M; j++)
  120.                 AddEdge(k, j);
  121.             k++;
  122.         }
  123.     }
  124.  
  125.     for(i=Base+; i<k; i++)
  126.     {///匹配的点添加反边
  127.         AddEdge( i, Ly[i] );
  128.     }
  129. }
  130.  
  131. /***************初始化********************/
  132. void InIt()
  133. {
  134.     ans.clear();
  135.     ans.resize(MAXN);
  136.  
  137.     memset(love, false, sizeof(love));
  138.     memset(dfn, false, sizeof(dfn));
  139.     memset(Head, -, sizeof(Head));
  140.     memset(Lx, false, sizeof(Lx));
  141.     memset(Ly, false, sizeof(Ly));
  142.  
  143.     cnt = Index = bnt = ;
  144. }
  145. /******************************************/
  146. int main()
  147. {
  148.     int T, t=;
  149.  
  150.     scanf("%d", &T);
  151.  
  152.     while(T--)
  153.     {
  154.         int i, j, v, Len;
  155.  
  156.         scanf("%d%d", &N, &M);
  157.         InIt();
  158.  
  159.         for(i=; i<=N; i++)
  160.         {
  161.             scanf("%d", &Len);
  162.  
  163.             while(Len--)
  164.             {
  165.                 scanf("%d", &v);
  166.                 AddEdge(i, v+Base);
  167.                 love[i][v] = true;
  168.             }
  169.         }
  170.  
  171.         XYL();
  172.  
  173.         for(i=; i<=N; i++)
  174.         {
  175.             if( !dfn[i] )
  176.                 Tarjan(i);
  177.         }
  178.  
  179.         printf("Case #%d:\n", t++);
  180.         for(i=; i<=N; i++)
  181.         {
  182.             v = belong[i];
  183.             Len = ans[v].size();
  184.  
  185.             int a[MAXN], k=;
  186.  
  187.             for(j=; j<Len; j++)
  188.             {///王子必须喜欢这个公主才行
  189.                 if(love[i][ ans[v][j] ] == true)
  190.                     a[k++] = ans[v][j];
  191.             }
  192.  
  193.             sort(a, a+k);
  194.  
  195.             printf("%d", k);
  196.             for(j=; j<k; j++)
  197.                 printf(" %d", a[j]);
  198.             printf("\n");
  199.         }
  200.     }
  201.  
  202.     return ; } 

H - Prince and Princess - HDU 4685(二分匹配+强连通分量)的更多相关文章

  1. Prince and Princess HDU - 4685(匹配 + 强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  2. hdu 4685 二分匹配+强连通分量

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 题解: 这一题是poj 1904的加强版,poj 1904王子和公主的人数是一样多的,并且给出 ...

  3. poj1904 二分图匹配+强连通分量

    http://poj.org/problem?id=1904 Description Once upon a time there lived a king and he had N sons. An ...

  4. HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  5. hdu 4685(匹配+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 思路:想了好久,终于想明白了,懒得写了,直接copy大牛的思路了,写的非常好! 做法是先求一次最 ...

  6. hdu 5093 二分匹配

    /* 题意:给你一些冰岛.公共海域和浮冰,冰岛可以隔开两个公共海域,浮冰无影响 求选尽可能多的选一些公共海域点每行每列仅能选一个. 限制条件:冰山可以隔开这个限制条件.即*#*可以选两个 预处理: * ...

  7. hdu 4169 二分匹配最大独立集 ***

    题意:有水平N张牌,竖直M张牌,同一方向的牌不会相交.水平的和垂直的可能会相交,求最少踢出去几张牌使剩下的牌都不相交. 二分匹配 最小点覆盖=最大匹配. 链接:点我 坐标点作为匹配的端点 #inclu ...

  8. Battle ships HDU - 5093二分匹配

    Battle shipsHDU - 5093 题目大意:n*m的地图,*代表海洋,#代表冰山,o代表浮冰,海洋上可以放置船舰,但是每一行每一列只能有一个船舰(类似象棋的車),除非同行或者同列的船舰中间 ...

  9. hdu 4685 简单匹配+Tarjan算法

    思路:首先看到这题以为能用poj1904的模版直接A掉,WA了几次,然后又TLE了几次.还是想到了正解. 一开始我想的大致方向已经是对的了.先是由王子向每个喜欢的公主建边,再求一次最大匹配,找出匹配后 ...

随机推荐

  1. ubuntu 修改运行级别

    只转载了成功的, 具体参见原文  http://www.2cto.com/os/201308/237632.html 第一种方法:(内核级别的)   Sudo vi /etc/default/grub ...

  2. 地址栏访问Action,后来方法执行两次

    SSH框架,在地址栏输入URL访问Action,后台访问会访问两次.很奇怪. 经排查,最终问题在于方法名称写错了.将getOpinionByPN()修改成queryOpinionByPN(),没有问题 ...

  3. webApp禁止用户保存图像

    img { -webkit-touch-callout: none; }

  4. 【转载】ASP.NET线程安全与静态变量的生命周期浅谈

    ASP.NET线程安全所涉及的是什么呢?让我们先来看看静态变量的生命周期问题,下面是我理解的静态变量的生命周期: void Application_Start开始 void Application_E ...

  5. MSChart使用之动态生成多个多行ChartArea

    前台代码: <asp:Chart ID=" > <Titles> <asp:Title Name="Title1" runat=" ...

  6. AFN发送请求失败

    发送请求出现这个错误 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Coc ...

  7. mysql操作1

    一.连接MYSQL.格式: mysql -h主机地址 -u用户名 -p用户密码1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录mysql\bin,再键入命令mysql -u root - ...

  8. ejabberd,erlang,简单看了一下,总结一下,很肤浅

    本来也没打算深入学习erlang,就是看一下他们的大概思路erlang每个自定义函数都能注册成进程,每个节点通过erl -name 'name@ip'.进去后,可以直接做远程调用,节点之间就靠一个连接 ...

  9. 初涉JavaScript模式 (12) : 沙箱模式

    引子 上一篇说了模块模式,而对于其中的命名空间模式其实也是有着一些问题,比如每添加一个模块或则深入叠加都会导致长命名,并且对于多个库的不同版本同时运行,一不小心就会污染全局标识,而这两天也发现了JSe ...

  10. grails框架中读取txt文件内容将内容转换为json格式,出现异常Exception in thread "main" org.json.JSONException: A JSONObject text must begin with '{' at character 1 of [...]

    Exception in thread "main" org.json.JSONException: A JSONObject text must begin with '{' a ...