题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685

题意:n个王子和m个公主,王子只能和他喜欢的公主结婚,公主可以和所有的王子结婚,输出所有王子可能的结婚对象,

必须保证王子与任意这些对象中的一个结婚,都不会影响到剩余的王子的配对数,也就是不能让剩余的王子中突然有一个人没婚可结了。

分析:这题是poj 1904的加强版,poj 1904的王子和公主数是相等的,这里可以不等,且poj 1904给出了一个初始完美匹配,但是这题就要自己求。

所以只要求出完美匹配之后,就和poj 1904的做法就完全相同了,这里就不在赘述了,可以参考:http://www.cnblogs.com/frog112111/p/3384261.html

那么怎么求出完美匹配呢?一开始我用多重匹配的匈牙利算法来做,但是怎么做都不对.......看了题解才恍然大悟=_=

先说几个坑,这题有点奇怪,就是所有王子都可以争着和同一个公主结婚,只要该王子喜欢该公主,感觉公主有点悲哀呀........

比如:2 2

1 1

1 1

输出的答案是:1 1   而不是  1 1

1 1             0

这里就是和poj 1904有点不一样的地方,坑了我好久.........

求完美匹配:

先对原图用匈牙利算法做一遍二分图匹配,但是还有可能剩余一些人还没匹配,只要虚拟出一些节点来匹配剩余的点就行了

假设王子有剩下的,那么每个剩下的王子就连一个虚拟的公主,这个公主被所有的王子都喜欢。

假设公主有剩下的,那么每个剩下的公主就连一个虚拟的王子,这个王子喜欢所有的公主

这样就构成完美匹配了,接下来就是和poj 1904一样了。

注意:虽然n和m才500,但是数组要开到2000才能过,可能是剩余太多顶点没匹配,所以要虚拟出比较多的顶点吧,我只开到1500,wa到死=_=

还有就是一些细节没处理好也贡献了好多wa,做了一天.........快奔溃了,最后参考别人的代码改来改去才AC,好艰辛,不过最终能过也算安慰了

果然想问题还是不够周全,不够细心

大三了都,哎,弱成一坨翔了~

 #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,false,sizeof(instack));
memset(flag,,sizeof(flag));
//scanf("%d%d",&n,&m);
n=Scan();
m=Scan();
maxn=max(n,m); //王子和公主数可能不同,为了建图方便去较大者,王子编号1--maxn,公主编号maxn+1--2*maxn
}
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]=true;
if(match[v]==||dfs(match[v]))
{
match[v]=u;
flag[u]=v;
return true;
}
}
}
return false;
}
void xiong() //二分匹配
{
int i;
memset(match,,sizeof(match));
for(i=;i<=maxn;i++)
{
memset(vis,false,sizeof(vis));
dfs(i);
}
}
void Tarjan(int u) //求强连通分量
{
int i,v;
low[u]=dfn[u]=++cnt;
sta[++top]=u;
instack[u]=true;
for(i=first[u];i!=-;i=edge[i].next)
{
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()
{
v=sta[top--];
instack[v]=false;
belong[v]=scc;
if(u==v)
break;
}
}
}
void build()
{
int i,k,v,j;
for(i=;i<=n;i++)
{
// scanf("%d",&k);
k=Scan();
while(k--)
{
// scanf("%d",&v);
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);
// printf("%d",count);
Out(count);
for(i=;i<count;i++) //输出
{
//printf(" %d",ans[i]);
putchar(' ');
Out(ans[i]);
}
// printf("\n");
putchar('\n');
}
}
int main()
{
int t,cas;;
// scanf("%d",&t);
t=Scan();
for(cas=;cas<=t;cas++)
{
init();
build();
printf("Case #%d:\n",cas);
solve();
}
return ;
}

hdu 4685(强连通分量+二分图)的更多相关文章

  1. hdu 4685(强连通分量+二分图的完美匹配)

    传送门:Problem 4685 https://www.cnblogs.com/violet-acmer/p/9739990.html 参考资料: [1]:二分图的最大匹配.完美匹配和匈牙利算法 [ ...

  2. HDU 3072 (强连通分量)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3072 题目大意:为一个有向连通图加边.使得整个图全连通,有重边出现. 解题思路: 先用Tarjan把 ...

  3. UVa 12167 & HDU 2767 强连通分量 Proving Equivalences

    题意:给出一个有向图,问最少添加几条有向边使得原图强连通. 解法:求出SCC后缩点,统计一下出度为0的点和入度为0的点,二者取最大值就是答案. 还有个特殊情况就是本身就是强连通的话,答案就是0. #i ...

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

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

  5. POJ 1904 King's Quest 强连通分量+二分图增广判定

    http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #inc ...

  6. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

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

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

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

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

  9. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

随机推荐

  1. 在MongoDB数据库中查询数据(上)

    在MongoDB数据库中查询数据(上) 在MongoDB数据库中,可以使用Collection对象的find方法从一个集合中查询多个数据文档,find方法使用方法如下所示: collection.fi ...

  2. PAT A1141 PAT Ranking of Institutions (25 分)——排序,结构体初始化

    After each PAT, the PAT Center will announce the ranking of institutions based on their students' pe ...

  3. docker执行第一个应用

    概念科普 Docker image:镜像是只读的,镜像中包含有需要运行的文件.镜像用来创建container,一个镜像可以运行多个container:镜像可以通过Dockerfile创建,也可以从Do ...

  4. 【Codeforces 1132F】Clear the String

    Codeforces 1132 F 题意:给一个串\(S\),问每次删除连续的一段相同字母,最少删几次将原串删空. 思路:考虑区间\(dp\),我们看要删多少次能把\([l,r]\)删空,那么最终答案 ...

  5. Android学习之APP点击功能闪退问题的处理一

    java代码如下: activity_main.xml代码如下: APP测试问题:安装好APP后,点击“点击事件”,APP会闪退 检查方向: 1.查看java代码中的成员变量textview是否初始化 ...

  6. Selenium:HTML测试报告

    自动化测试过程中,获得用例的执行结果后,需要有具象化.简洁明了的测试结果,比如:用例执行时间.失败用例数.失败的原因等,这时候,就需要用到测试报告. HTML测试报告是python语言自带的单元测试框 ...

  7. 软概(lesson 1):Javaweb实现用户登录界面

    一.问题描述 二.网站系统开发所需要的技术 网站界面开发:html 后台所需要的技术:java基本内容,数据库语句,连接数据库实现增删改查 本题所用技术:数据库链接以及增加功能,基本html语句 技术 ...

  8. win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建

    win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建 重编译的优点:能够调试的时候看OpenCV的源码. 重编译要得到的东西:Debug版本号和Release版本号 ...

  9. 在centos 7上安装BIMServer

    下载bimserverwar-1.5.85.war https://github.com/opensourceBIM/BIMserver/releases mkdir -p /opt/bim cd / ...

  10. python3通过gevent.pool限制协程并发数量

    协程虽然是轻量级的线程,但到达一定数量后,仍然会造成服务器崩溃出错.最好的方法通过限制协程并发数量来解决此类问题. server代码: #!/usr/bin/env python # -*- codi ...