题解:

二分图匹配

对于每一个单身狗

见一个虚拟的人

然后就可以做了

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int M=+;
struct EDGE{int v,next;}edge[M];
int first[N],low[N],dfn[N],sta[M],belong[N];
int ans[N],match[N],flag[N];
bool instack[N],vis[N];
int n,m,g,cnt,top,scc,maxn;
int Scan()
{
int res=,ch,flag=;
if ((ch=getchar())=='-')
flag=;
else if (ch>=''&&ch<='')
res=ch-'';
while((ch=getchar())>=''&&ch<='')
res=res*+ch-'';
return flag?-res:res;
}
void Out(int a)
{
if (a>)
Out(a/);
putchar(a%+'');
}
void AddEdge(int u,int v)
{
edge[g].v=v;
edge[g].next=first[u];
first[u]=g++;
}
int min(int a,int b)
{
return a<b?a:b;
}
int max(int a,int b)
{
return a>b?a:b;
}
void init()
{
g=cnt=top=scc=;
memset(first,-,sizeof(first));
memset(dfn,,sizeof(dfn));
memset(instack,,sizeof(instack));
memset(flag,,sizeof(flag));
n=Scan();
m=Scan();
maxn=max(n,m);
}
bool dfs(int u)
{
int i,v;
for (i=first[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if (!vis[v])
{
vis[v]=;
if (match[v]==||dfs(match[v]))
{
match[v]=u;
flag[u]=v;
return ;
}
}
}
return ;
}
void xiong()
{
int i;
memset(match,,sizeof(match));
for (i=;i<=maxn;i++)
{
memset(vis,,sizeof(vis));
dfs(i);
}
}
void Tarjan(int u)
{
low[u]=dfn[u]=++cnt;
sta[++top]=u;
instack[u]=;
for (int i=first[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if (!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if (instack[v])low[u]=min(low[u],dfn[v]);
}
if (low[u]==dfn[u])
{
scc++;
while ()
{
int v=sta[top--];
instack[v]=;
belong[v]=scc;
if (u==v)
break;
}
}
}
void build()
{
int i,k,v,j;
for (i=;i<=n;i++)
{
k=Scan();
while(k--)
{
v=Scan();
AddEdge(i,v+maxn);
}
}
xiong();
int all=*maxn;
for (i=;i<=maxn;i++)
{
if (!flag[i])
{
all++;
for (j=;j<=maxn;j++)
AddEdge(j,all);
match[all]=i;
flag[i]=all;
}
} for (i=maxn+;i<=*maxn;i++)
{
if (!match[i])
{
all++;
for (j=maxn+;j<=*maxn;j++)
AddEdge(all,j);
flag[all]=i;
match[i]=all;
}
}
for (i=;i<=all;i++)
if (flag[i])AddEdge(flag[i],i);
}
void solve()
{
int i,u,v;
for (i=;i<=maxn;i++)
if (!dfn[i])Tarjan(i);
for (u=;u<=n;u++)
{
int count=;
for (i=first[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if (belong[u]==belong[v])
{
if (v-maxn>m)
continue;
ans[count++]=v-maxn;
}
}
sort(ans,ans+count);
Out(count);
for (i=;i<count;i++)
{
putchar(' ');
Out(ans[i]);
}
putchar('\n');
}
}
int main()
{
int t=Scan();
for (int cas=;cas<=t;cas++)
{
init();
build();
printf("Case #%d:\n",cas);
solve();
}
return ;
}

hdu4685的更多相关文章

  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. HDU4685 Prince and Princess【强连通】

    题意: 有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚,公主就比较悲惨, 跟谁结婚都行.然后输出王子可能的结婚对象,必须保证王子与任意这些对象中的一个结婚,都不会影 ...

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

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

  5. hdu4685 最大匹配可能性

    题意:       给你n个王子和m个公主,每个王子可以和自己喜欢的公主结婚,问你在不影响最大匹配的前提下每个王子都可以去哪些公主. 思路:       所有王子向他喜欢的公主连一条边,然后匹配一遍, ...

  6. Prince and Princess

    hdu4685:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚公 ...

  7. POJ1904 强联通(最大匹配可能性)

    题意:       有n个王子,n个公主,然后给你每个王子喜欢的公主,最后问你在不影响最大匹配的前提下,每个王子可以匹配那些公主. 思路:       是hdu4685的减弱版,之前研究过hdu468 ...

随机推荐

  1. Salesforce学习第一天

    好久没有在博客园发布学习博客了,开学事情多,奇葩心思多嘛,谅解.现在在一家公司实习Salesforce开发,每天都在看英文文档,然后学着操作,只可惜没人能培训下,学习起来进度比较慢.英文的文档看的思绪 ...

  2. JMS--消息头

    一个消息对象分为三部分:消息头(Headers),属性(Properties)和消息体(Payload).对于StreamMessage和MapMessage,消息本身就有特定的结构,而对于TextM ...

  3. centos7下配置iptables实现外网访问内网服务器

    说明:Centos 7 默认的防火墙是 firewall,安装iptables之前需关闭Firewall 外网机器:外网ip:120.25.71.183内网ip:10.1.1.23 内网机器:内网ip ...

  4. 20145316许心远《Java学习笔记(第8版)》课程总结

    20145316许心远<Java学习笔记(第8版)>课程总结 每周读书笔记链接汇总 ▪ 第一周读书笔记 ▪ 第二周读书笔记 ▪ 第三周读书笔记 ▪ 第四周读书笔记 ▪ 第五周读书笔记 ▪ ...

  5. 屏蔽信号的多路选择I/O

    前边提到了多路I/O的方法,这一章屏蔽信号的多路选择与之前的多路I/O一致,只是增加了屏蔽信号的作用.多路选择I/O中我们使用的是select函数,屏蔽信号的多路选择I/O使用的是pselect函数, ...

  6. Python 实例2—购物车

    老男孩教学学习笔记 """启动程序后,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒可随机退出,退出 ...

  7. 20145331 《Java程序设计》第2周学习总结

    20145331<Java程序设计>第2周学习总结 教材学习内容总结 3.1 类型.变量与运算符 •注释://(单行注释).//(多行注释)./ */(javadoc文档注释 )注释的内容 ...

  8. Show Desktop Pro FAQ

    Q. Will the desktop background image be restored after quit? A: Yes. Right now, "Hide icons&quo ...

  9. Flutter中集成Font Awesome

    1.添加引用 在 pubspec.yaml文件中,加入 font awesome的引用 dependencies: flutter: sdk: flutter # The following adds ...

  10. Codeforces - 828E DNA Evolution —— 很多棵树状数组

    题目链接:http://codeforces.com/contest/828/problem/E E. DNA Evolution time limit per test 2 seconds memo ...