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

1 2  

2 1 2
如果不添加虚拟点做成匹配,只会匹配成功一个,这样就找不出来环了,所以需要添加虚拟的王子和公主,虚拟的王子喜欢所有的公主,虚拟的公主被所有的王子喜欢,注意都是王子喜欢公主的,公主没有选择喜欢的权利(确实有点悲哀- -)
*************************************************************************
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std; const int MAXN = ;
const int Base = ;
///base 王子的编号从1开始 公主的编号从base+1开始, 虚拟点的编号从base*2+1开始
int N, M;
bool love[][];
vector< vector <int> >ans;
/***************邻接表*********************/
struct Edge{int v, next;}e[MAXN*MAXN];
int Head[MAXN], cnt; void AddEdge(int u, int v)
{
    e[cnt].v = v;
    e[cnt].next = Head[u];
    Head[u] = cnt++;
}
/**************Tarjan**********************/
int dfn[MAXN], low[MAXN], Index;
int Stack[MAXN], instack[MAXN], top;
int belong[MAXN], bnt; void Tarjan(int i)
{
    int v;     dfn[i] = low[i] = ++Index;
    Stack[++top] = i, instack[i] = true;     for(int j=Head[i]; j!=-; j=e[j].next)
    {
        v = e[j].v;         if( !dfn[v] )
        {
            Tarjan(v);
            low[i] = min(low[i], low[v]);
        }
        else if( instack[v] )
            low[i] = min(low[i], dfn[v]);
    }     if(low[i] == dfn[i])
    {
        ++bnt;
        do
        {
            v = Stack[top--];
            instack[v] = false;
            belong[v] = bnt;
            if(v > Base)
                ans[bnt].push_back(v-Base);
        }
        while(i != v);
    }
}
/***************匈牙利********************/
int Lx[MAXN], Ly[MAXN];
bool used[MAXN]; bool Find(int i)
{
    for(int j=Head[i]; j!=-; j=e[j].next)
    {
        int v = e[j].v;         if( !used[v] )
        {
            used[v] = true;
            if( !Ly[v] || Find(Ly[v]) )
            {
                Ly[v] = i;
                Lx[i] = v;                 return true;
            }
        }
    }     return false;
}
void XYL()///顺便添加虚拟点
{
    int i, j, k, sum=;     for(i=; i<=N; i++)
    {
        memset(used, false, sizeof(used));
        sum += Find(i);
    }     k = Base *  + ;///虚拟点开开始处     for(i=; i<=N; i++)
    {///遍历王子部分,看那个王子没有匹配,为他虚拟一个公主,这个公主所有的王子都喜欢
        if(Lx[i] == false)
        {
            Lx[i] = k;
            Ly[k] = i;             for(j=; j<=N; j++)
                AddEdge(j, k);
            k++;
        }
    }     for(i=Base+; i<=Base+M; i++)
    {///遍历公主部分,看哪个公主没有匹配,为她虚拟一个王子,这个王子喜欢所有的公主
        if(Ly[i] == false)
        {
            Lx[k] = i;
            Ly[i] = k;             for(j=Base+; j<=Base+M; j++)
                AddEdge(k, j);
            k++;
        }
    }     for(i=Base+; i<k; i++)
    {///匹配的点添加反边
        AddEdge( i, Ly[i] );
    }
} /***************初始化********************/
void InIt()
{
    ans.clear();
    ans.resize(MAXN);     memset(love, false, sizeof(love));
    memset(dfn, false, sizeof(dfn));
    memset(Head, -, sizeof(Head));
    memset(Lx, false, sizeof(Lx));
    memset(Ly, false, sizeof(Ly));     cnt = Index = bnt = ;
}
/******************************************/
int main()
{
    int T, t=;     scanf("%d", &T);     while(T--)
    {
        int i, j, v, Len;         scanf("%d%d", &N, &M);
        InIt();         for(i=; i<=N; i++)
        {
            scanf("%d", &Len);             while(Len--)
            {
                scanf("%d", &v);
                AddEdge(i, v+Base);
                love[i][v] = true;
            }
        }         XYL();         for(i=; i<=N; i++)
        {
            if( !dfn[i] )
                Tarjan(i);
        }         printf("Case #%d:\n", t++);
        for(i=; i<=N; i++)
        {
            v = belong[i];
            Len = ans[v].size();             int a[MAXN], k=;             for(j=; j<Len; j++)
            {///王子必须喜欢这个公主才行
                if(love[i][ ans[v][j] ] == true)
                    a[k++] = ans[v][j];
            }             sort(a, a+k);             printf("%d", k);
            for(j=; j<k; j++)
                printf(" %d", a[j]);
            printf("\n");
        }
    }     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. python文件处理--笔记

    之前一段时间一直在忙着写毕业论文,盲评搞得人心惶惶,以致于都没有看书,最近需要补上前面落下的东西. <Python3程序开发指南> 1.二进制数据的读写 二进制格式通常是占据磁盘空间最小. ...

  2. 如何开通www国际域名个人网站

    欢迎访问我的域名http://www.baiqiantao.xyz 一.准备知识 什么是域名? 所有以www开头的域名,就是国际域名:不以www开头的域名,都是为子域名. 域名都有后缀,后缀是有意义的 ...

  3. Bootstrap Modal 框 alert confirm loading

    /** * Created by Administrator on 2016/5/4. */ /** * 模态窗口 */ window.Modal = { tpls:{ alert:'<div ...

  4. iOS开发常用的第三方框架

    1. AFNetworking 在众多iOS开源项目中,AFNetworking可以称得上是最受开发者欢迎的库项目.AFNetworking是一个轻量级的iOS.Mac OS X网络通信类库,现在是G ...

  5. UICollectionView出现the behavior of the UICollectionViewFlowLayout is not defined because:

    2015-01-28 21:55:17.790 Demo[636:9351] the behavior of the UICollectionViewFlowLayout is notdefined ...

  6. 【USACO 2.2.4】派对灯

    [描述] 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码. 这些灯都连接到四个按钮: 按钮1:当按下此按钮,将改变所有的灯:本来亮着的灯就熄 ...

  7. 破解Inode客户端使用笔记本共享WIFI

    由于住在学校的公寓里面,所以使用的是校园网,但是校园网限制了无线的使用,强制所有网络用户使用INode网络客户端,这个客户端不但很丑很难看,而且每天联网十分费劲,费了半天的力气终于联上网了,可是一眨眼 ...

  8. extjs中datefield组件的使用

    xtype: 'datefield', id: 'dateShangmfa', name: 'dateShangmfa', fieldLabel: '日期',//设置标签文本 editable: fa ...

  9. localstorage || globalStorage || userData

    globalStorage 这个也是html5中提出来,在浏览器关闭以后,使用globalStorage存储的信息仍能够保留下来,并且存储容量比IE的userdata大得多,一个域下面是5120k.和 ...

  10. 编写可维护的javascript代码--- 2015.11.22(注释)

    1.单行注释 // 这是一句单行注释 2.多行注释 /* 这里是代码 */     /*  这里都是注释 1232132  */      java的注释风格 /* * 另一段注释 * 这段注释包含2 ...