hdu4685
题解:
二分图匹配
对于每一个单身狗
见一个虚拟的人
然后就可以做了
代码:
#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的更多相关文章
- 强连通+二分匹配(hdu4685 Prince and Princess)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- HDU4685 Prince and Princess 完美搭配+良好的沟通
意甲冠军:今天,有n王子,m公主.现在给他们配对,与王子会嫁给一个男人,他喜欢.公主无法做出选择. 这标题去咬硬,还有一类似的题目poj1904.那个题目也是给王子与公主配对,但那个是王子公主各n个, ...
- HDU4685 Prince and Princess【强连通】
题意: 有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚,公主就比较悲惨, 跟谁结婚都行.然后输出王子可能的结婚对象,必须保证王子与任意这些对象中的一个结婚,都不会影 ...
- HDU4685:Prince and Princess(二分图匹配+tarjan)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- hdu4685 最大匹配可能性
题意: 给你n个王子和m个公主,每个王子可以和自己喜欢的公主结婚,问你在不影响最大匹配的前提下每个王子都可以去哪些公主. 思路: 所有王子向他喜欢的公主连一条边,然后匹配一遍, ...
- Prince and Princess
hdu4685:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚公 ...
- POJ1904 强联通(最大匹配可能性)
题意: 有n个王子,n个公主,然后给你每个王子喜欢的公主,最后问你在不影响最大匹配的前提下,每个王子可以匹配那些公主. 思路: 是hdu4685的减弱版,之前研究过hdu468 ...
随机推荐
- $Python技巧大全
知乎上有一个问题:Python 有什么奇技淫巧?其中有各种不按套路出牌的招数,也不乏一些惊为天人的"奇技淫巧",会让你大呼:居然还有这种操作??? 本文就是对日常使用过的或者觉得很 ...
- iOS开发之CoreData数据存储
iOS开发之CoreData数据存储 参考资料:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreD ...
- 微服务-使用Redis实现分布式缓存
在单体中对于key信息和用户信息是放在内存中放的,通过session进行管理. 微服务是要放在分布式缓存中,以实现服务的无状态化. @Autowired private StringRedisTemp ...
- JS与JAVA数据类型的区别
JavaScript与Java数据类型的区别 阅读目录 Number String Boolean Null Undefined Object 今天开始正式认真学习js,虽然在平常j2ee开发中也 ...
- webservice使用方法
1,右击项目选择-->添加服务引用: 填写一个 命名空间名称; 2, 实例化 命名空间名称 ; 选择 带client的服务名称进行初始化 3,开始调用方法 // 带参数的webservice ...
- vsftpd搭建ftp服务,并实现虚拟用户访问
安装vsftpd服务: yum install vsftpd -y [root@wadeson ~]# rpm -ql vsftpd /etc/logrotate.d/vsftpd /etc/pam. ...
- Linux下程序的机器级表示学习心得
Linux下程序的机器级表示学习心得 上周学习完Linux程序的机器级表示后,对于其中有些还是掌握的不太透彻.对于老师提出的关于本章一些细节的问题还是有不会,所以又重新温习了一下上周的学习内容,以下为 ...
- markdown工作随笔总结
1. 锚点 (使用方法和链接很像) ## 目录 1. [命名](#命名) ....... **[返回顶部](#目录)** ## 命名 ###命名原则 可以从返回顶部回到目录,也可以点击目录的命名跳到命 ...
- 重新想,重新看——CSS3变形,过渡与动画②
本篇文章主要用来归纳总结CSS3变形属性. CSS3变形属性大致可以分为以下三个部分: 变形控制属性 2D变形函数 3D变形函数 下面将对其一一进行分析: 1.变形控制属性 所谓的变形控制属性主要指“ ...
- [翻译]理解CSS模块方法
在这个前端发展日新月异的世界,能够找到有所影响的概念相当困难,而将其准确无误的传达,让人们愿意尝试,更是难上加难. 拿CSS来看,在我们写CSS时,工具侧最大的变化,也就是CSS处理器的使用,如:可能 ...