UVALive-2966 King's Quest(强连通+二分图匹配)
题目大意:有n个男孩和和n个女孩,已只每个男孩喜欢的女孩。一个男孩只能娶一个女孩、一个女孩只能嫁一个男孩并且男孩只娶自己喜欢的女孩,现在已知一种他们的结婚方案,现在要求找出每个男孩可以娶的女孩(娶完之后不能影响其他男孩结婚)。
题目分析:已知的结婚方案是一个完全匹配。从每个男孩出发向他喜欢的女孩连一条有向边,得到一张完全二分图,实际上这道题是让判断去掉哪一些边使图仍然完全匹配。设男生x1和女生y1是已知方案中要结婚的两个人,假如x1抛弃y1,选择了他也喜欢的y2结婚(也就是去掉边x1->y2),那么就得需要让原方案中y2的结婚对象x2选择一个他喜欢的女孩(不能再是y2)结婚,一直进行下去这个过程,y1终究会被选走(如果去边之后的图仍完全匹配)。这正是匈牙利算法的过程,但这样要超时。但是,如果将从y1出发连一条边到x1,那么这个过程所经过的所有点就构成了一个强连通分量。对于某个男孩,娶和他在同一强连通分量的任何一个女孩都不会影响其他男孩结婚。
代码如下:
# include<iostream>
# include<cstdio>
# include<stack>
# include<vector>
# include<cstring>
# include<iostream>
using namespace std;
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b) const int N=2005;
struct Edge
{
int to,nxt;
};
Edge e[N*100+N];
stack<int>S;
int scc_cnt,dfs_cnt,cnt,n,head[2*N],sccno[2*N];
int low[2*N],pre[2*N],G[N][N];
vector<int>ans; void add(int u,int v)
{
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
} void dfs(int u)
{
S.push(u);
low[u]=pre[u]=++dfs_cnt;
for(int i=head[u];i!=-1;i=e[i].nxt){
int v=e[i].to;
if(!pre[v]){
dfs(v);
low[u]=min(low[u],low[v]);
}else if(!sccno[v])
low[u]=min(low[u],pre[v]);
}
if(low[u]==pre[u]){
++scc_cnt;
while(1){
int x=S.top(); S.pop();
sccno[x]=scc_cnt;
if(x==u) break;
}
}
} void findScc()
{
scc_cnt=dfs_cnt=0;
CL(pre,0);
CL(sccno,0);
REP(i,1,n+1) if(!pre[i]) dfs(i);
} int main()
{
while(~scanf("%d",&n))
{
int k,a;
cnt=0;
CL(G,0);
CL(head,-1);
REP(i,1,n+1){
scanf("%d",&k);
while(k--)
{
scanf("%d",&a);
add(i,a+n);
G[i][a]=1;
}
}
REP(i,1,n+1){
scanf("%d",&a);
add(a+n,i);
}
findScc();
REP(i,1,n+1){
ans.clear();
REP(j,n+1,2*n+1) if(G[i][j-n]&&sccno[i]==sccno[j])
ans.push_back(j-n);
printf("%d",ans.size());
REP(j,0,ans.size()) printf(" %d",ans[j]);
printf("\n");
}
}
return 0;
}
UVALive-2966 King's Quest(强连通+二分图匹配)的更多相关文章
- POJ1904 King's Quest(完备匹配可行边:强连通分量)
题目大概就是说给一张二分图以及它的一个完备匹配,现在问X部的各个点可以与Y部那些些点匹配,使得X部其余点都能找到完备匹配. 枚举然后匹配,当然不行,会超时. 这题的解法是,在二分图基础上建一个有向图: ...
- POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...
- POJ 1904 King's Quest (强连通分量+完美匹配)
<题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...
- POJ 1904 King's Quest 强连通分量+二分图增广判定
http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #inc ...
- UVALive 5903 Piece it together(二分图匹配)
给你一个n*m的矩阵,每个点为'B'或'W'或'.'.然后你有一种碎片.碎片可以旋转,问可否用这种碎片精确覆盖矩阵.N,M<=500 WB <==碎片 W 题目一看,感觉是精确覆盖(最近 ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
- POJ - 1904 King's Quest (强连通)
题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...
- POJ1904:King's Quest(强连通+思维)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 10352 Accepted: 3815 题目 ...
- poj1904 二分图匹配+强连通分量
http://poj.org/problem?id=1904 Description Once upon a time there lived a king and he had N sons. An ...
随机推荐
- 把大象装进冰箱的N种方法
作者:折剑头链接:https://www.zhihu.com/question/49214119/answer/115728034来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...
- Myeclipse 2013 professional 破解
破解前要先关闭Myeclipse2013 1.(1)输入usercode可以随便输入,(2)然后选择Myeclipse的版本,(3)点击systemid按钮 2.然后点击Tools菜单栏下的Rebui ...
- JAVA中传递的值还是引用的问题
public static void main(String[] args) { /*byte b[] = new byte[1024*1024*50]; System.out.println(b); ...
- MFC截图和界面刷新相关问题
问题描写叙述: 就是首先用CDC来截图,保存图片的路径通过dlg窗体来手动设置并传入.但是截下来的图片就会连带那个对话框也截图下来. 就是这样.我想截后面那个图.前面这 ...
- Spark之Task原理分析
在Spark中,一个应用程序要想被执行,肯定要经过以下的步骤: 从这个路线得知,最终一个job是依赖于分布在集群不同节点中的task,通过并行或者并发的运行来完成真正的工作.由此可见 ...
- spark mllib和ml类里面的区别
mllib是老的api,里面的模型都是基于RDD的,模型使用的时候api也是有变化的(model这里是naiveBayes), (1:在模型训练的时候是naiveBayes.run(data: RDD ...
- Spring中基于Java的配置@Configuration和@Bean用法
spring中为了减少xml中配置,可以声明一个配置类(例如SpringConfig)来对bean进行配置. 一.首先,需要xml中进行少量的配置来启动Java配置: <?xml version ...
- 实现linux下的ls
实现linux下的ls ls的使用 ls -a 列出文件下所有的文件,包括以"."开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录). ls -l ...
- Python中被双下划线包围的魔法方法
基本的魔法方法 __new__(cls[, ...]) 用来创建对象 1. __new__ 是在一个对象实例化的时候所调用的第一个方法 2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __i ...
- java线程初写,陆续更新中。。
(1)什么是线程?线程,是程序执行流的最小单元.线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享 ...