题意:

有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚,公主就比较悲惨, 跟谁结婚都行。然后输出王子可能的结婚对象,必须保证王子与任意这些对象中的一个结婚,都不会影响到剩余的王子的配对数,也就是不能让剩余的王子中突然有一个人没婚可结了。

思路:

对每个没有匹配的公主,建一个虚拟的王子,让他们变成匹配,然后由这个虚拟王子向每个公主建边。对每个没有匹配的王子,建一个虚拟的公主,让他们变成匹配,然后每个王子向这个虚拟公主建边。求一个Tarjan,判断是否为1个强连通分量即可。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define maxn 2005 using namespace std; int dfn[maxn],low[maxn],vi[maxn],Stack[maxn],head[maxn],id[maxn],n,e,lab,num,top,ans[maxn];
int graphic[][],m,match[maxn],cho[maxn],mm; struct Edge{
int u,v,next;
}edge[]; vector<int> q[maxn],girl[maxn]; void init()
{
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vi,,sizeof(vi));
memset(head,-,sizeof(head));
memset(id,,sizeof(id));
memset(graphic,,sizeof(graphic));
memset(cho,,sizeof(cho));
memset(match,-,sizeof(match));
memset(ans,,sizeof(ans));
for(int i=;i<maxn;i++)
q[i].clear(),girl[i].clear();
e=lab=num=top=mm=;
} void add(int u,int v)
{
edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
} int dfs(int u)//匈牙利算法
{
int i;
for(i=;i<=m;i++)
{
if(!vi[i]&&graphic[u][i])
{
vi[i]=;
if(match[i]==-||dfs(match[i]))
{
match[i]=u;
return ;
}
}
}
return ;
} int Tarjan(int u)
{
dfn[u]=low[u]=++lab;
vi[u]=;
Stack[top++]=u;
int i,v;
for(i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
if(vi[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
++num;
do{
i=Stack[--top];
vi[i]=;
id[i]=num;
}while(i!=u);
}
return ;
} void solve()
{
int i,j;
for(i=;i<=n+m+mm;i++)
if(!dfn[i])
Tarjan(i);
for(i=n+;i<=n+m;i++)
{
q[id[i]].push_back(i-n);
}
int cnt=;
for(i=;i<=n;i++)
{
int size=q[id[i]].size();
cnt=;
for(j=;j<size;j++)
{
if(graphic[i][q[id[i]][j]])
ans[cnt++]=q[id[i]][j];
}
printf("%d",cnt);
for(j=;j<cnt;j++)
printf(" %d",ans[j]);
printf("\n");
}
} int main()
{
int a,b,i,j,t,Case=;
scanf("%d",&t);
while(t--)
{
init();
scanf("%d%d",&n,&m);
for(i=;i<=n;i++)
{
scanf("%d",&a);
while(a--)
{
scanf("%d",&b);
add(i,b+n);
graphic[i][b]=;
}
}
int num=;
memset(match,-,sizeof(match));
for(i=;i<=n;i++)
{
memset(vi,,sizeof(vi));
if(dfs(i))
num++;
}
mm=;
for(i=;i<=m;i++)
{
if(match[i]==-)
{
mm++;
add(n+m+mm,i+n);
add(i+n,n+m+mm);
for(j=;j<=m;j++)
add(n+m+mm,j+n);
}
else
{
cho[match[i]]=;
}
add(i+n,match[i]);
}
for(i=;i<=n;i++)
{
if(cho[i]==)
{
mm++;
add(i,n+m+mm);
add(n+m+mm,i);
for(j=;j<=n;j++)
add(j,n+m+mm);
}
}
memset(vi,,sizeof(vi));
printf("Case #%d:\n",++Case);
solve();
}
return ;
}

HDU4685 Prince and Princess【强连通】的更多相关文章

  1. 强连通+二分匹配(hdu4685 Prince and Princess)

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

  2. HDU4685 Prince and Princess 完美搭配+良好的沟通

    意甲冠军:今天,有n王子,m公主.现在给他们配对,与王子会嫁给一个男人,他喜欢.公主无法做出选择. 这标题去咬硬,还有一类似的题目poj1904.那个题目也是给王子与公主配对,但那个是王子公主各n个, ...

  3. HDU4865 Prince and Princess 强连通分量+二分图判定

    这个题就是建图费点劲,别的和我上一篇博客一样 然后,参考思路请戳这里http://www.cnblogs.com/wally/archive/2013/09/12/3317883.html 补充:这个 ...

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

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

  5. 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 ...

  6. HDU4685:Prince and Princess(二分图匹配+tarjan)

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

  7. 10635 - Prince and Princess

    Problem D Prince and Princess Input: Standard Input Output: Standard Output Time Limit: 3 Seconds In ...

  8. UVa10653.Prince and Princess

    题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  9. uva 10635 - Prince and Princess(LCS)

    题目连接:10635 - Prince and Princess 题目大意:给出n, m, k,求两个长度分别为m + 1 和 k + 1且由1~n * n组成的序列的最长公共子序列长的. 解题思路: ...

随机推荐

  1. python下对appium服务端的操作

    appium -p 4703 -bp 5500 -U 127.0.0.1:5005 -p 指的是·appium的服务器端口 -bp 指的是 连接安卓设备端口 -U 指的是 安卓设备 大体思路: 1. ...

  2. Django前端获取后端数据之前端自定义函数

    在写网站的时候遇到了一个问题: Django在后端向前端传数据时,多数会使用dict字典来传送多个数据,但前端只能遍历,没有一个用key取到value值的方法可以直接使用 如果作为一个list传递到前 ...

  3. QAU 18校赛 J题 天平(01背包 判断能否装满)

    问题 J: 天平 时间限制: 1 Sec  内存限制: 128 MB提交: 36  解决: 9[提交][状态][讨论版][命题人:admin] 题目描述 天平的右端放着一件重量为w的物品.现在有n个重 ...

  4. importlib 模块

    根据字符串的模块名实现动态导入模块的库 目录结构 ├── aaa.py ├── bbb.py └── mypackage ├── __init__.py └── xxx.py bbb.py impor ...

  5. day25 初始面向对象

    类 有具体规范,无具体值对象 有具体的值 dict 类d = {"":""} 对象 自定义一个类格式: class 类名: # 可以跟()或者不跟 属性 = ' ...

  6. day14 装饰器模拟验证附加功能

    user_list=[ {'}, {'}, {'}, {'}, ] current_dic={'username':None,'login':False} def auth_func(func): d ...

  7. [HNOI2005]狡猾的商人 ,神奇做法——贪心

    洛谷P2294 [HNOI2005]狡猾的商人 ,神奇做法--贪心 看到大牛都是写的差分约束或带权并查集,本蒟蒻都不太会(还是用差分约束过了的QAQ),但是想出一种贪心的策略,运用神奇的优先队列实现. ...

  8. android 让真机显示 DeBug Log调试信息

    真机默认是不开启Log 开关的,这么来说我们如果使用真机来搞程序测试的话,需要做以下几个步骤: 下面以华为手机为例开启手机的log功能:  1.在拨号界面输入:*#*#2846579#*#*  进入测 ...

  9. 洛谷 P4100 [HEOI2013]钙铁锌硒维生素 解题报告

    P4100 [HEOI2013]钙铁锌硒维生素 题目描述 银河队选手名单出来了!小林,作为特聘的营养师,将负责银河队选手参加 宇宙比赛的饮食. 众所周知,前往宇宙的某个星球,通常要花费好长好长的时间, ...

  10. Python中的join()函数的用法及列表推导式

    [红色为转载后新增部分] 函数:string.join() Python中有join()和os.path.join()两个函数,具体作用如下: join():连接字符串数组.将字符串.元组.列表中的元 ...