POJ1904 King's Quest(完备匹配可行边:强连通分量)
题目大概就是说给一张二分图以及它的一个完备匹配,现在问X部的各个点可以与Y部那些些点匹配,使得X部其余点都能找到完备匹配。
枚举然后匹配,当然不行,会超时。
这题的解法是,在二分图基础上建一个有向图:原二分图中边(x,y)连<x,y>的弧,对于那个已知的匹配中的所有边(x,y)连<y,x>的弧,然后对于X部各个点x如果它到Y部的y点有直接的边且它们在同一个强连通分量,那么x就能和y匹配。
我对这个解法的理解是这样的,类似于匈牙利算法的增广路:
- 如果x和y就属于给定的那个完备匹配那它们本来就在强连通分量上;
- 否则,就在原匹配的基础上在构造的有向图上走,看能否找到一条“增广路”(其实不是增广路)去修正,看能否使得x匹配的点改成y——
x走向y,这条边必定不属于原匹配,那么这条边加入匹配集合
y走向x1,这条边必定属于原匹配,那么这条边从匹配集合中删去
x1走向y1,这条边必定不属于原匹配,那么这条边加入匹配集合
…… …… ……
最后如果就存在一个yn走能向x,这条边必定属于原匹配,删去;而删除这条边后,就没有和最开头加入匹配集合的那条(x,y)的边存在公共点的边了,(x,y)就是一个合法的匹配
感觉这解法很巧。而这二分图上的边最大独立集,性质挺多的,感觉也挺难运用这些性质。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 4444
#define MAXM 2222*2222 struct Edge{
int v,next;
}edge[MAXM];
int NE,head[MAXN];
void addEdge(int u,int v){
edge[NE].v=v; edge[NE].next=head[u];
head[u]=NE++;
} int top,stack[MAXN];
bool instack[MAXN];
int dn,dfn[MAXN],low[MAXN];
int bn,belong[MAXN];
void tarjan(int u){
dfn[u]=low[u]=++dn;
stack[++top]=u; instack[u]=;
for(int i=head[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]){
int v; ++bn;
do{
v=stack[top--];
instack[v]=;
belong[v]=bn;
}while(u!=v);
}
} int main(){
int n,a,b;
while(~scanf("%d",&n)){
NE=;
memset(head,-,sizeof(head));
for(int i=; i<=n; ++i){
scanf("%d",&a);
while(a--){
scanf("%d",&b);
addEdge(i,b+n);
}
}
for(int i=; i<=n; ++i){
scanf("%d",&a);
addEdge(a+n,i);
}
top=dn=bn=;
memset(dfn,,sizeof(dfn));
memset(instack,,sizeof(instack));
for(int i=; i<=*n; ++i){
if(dfn[i]==){
tarjan(i);
}
}
for(int u=; u<=n; ++u){
int cnt=;
bool vis[MAXN]={};
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(belong[u]==belong[v]){
++cnt;
vis[v-n]=;
}
}
printf("%d",cnt);
for(int i=; i<=n; ++i){
if(vis[i]){
printf(" %d",i);
}
}
putchar('\n');
}
}
return ;
}
POJ1904 King's Quest(完备匹配可行边:强连通分量)的更多相关文章
- UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)
UVA1327 King's Quest POJ1904 King's Quest 题意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚.现有一个匹配表,将每个王子都与一个自己 ...
- POJ1904 King's Quest
King's Quest Language:Default King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submission ...
- POJ1904:King's Quest(强连通+思维)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 10352 Accepted: 3815 题目 ...
- 【建模+强连通分量】POJ1904 King's Quest
Description 一个国王有n个王子,同时有n个女孩.每个王子都有自己喜欢的若干个女孩,现给定一个合法的完备匹配(也就是一个王子娶其中一个自己喜欢女孩),求每个王子可以选择哪些女孩可以让剩下的每 ...
- HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...
- POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...
- King's Quest —— POJ1904(ZOJ2470)Tarjan缩点
King's Quest Time Limit: 15000MS Memory Limit: 65536K Case Time Limit: 2000MS Description Once upon ...
- POJ 1904 King's Quest (强连通分量+完美匹配)
<题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...
- UVALive-2966 King's Quest(强连通+二分图匹配)
题目大意:有n个男孩和和n个女孩,已只每个男孩喜欢的女孩.一个男孩只能娶一个女孩.一个女孩只能嫁一个男孩并且男孩只娶自己喜欢的女孩,现在已知一种他们的结婚方案,现在要求找出每个男孩可以娶的女孩(娶完之 ...
随机推荐
- Codeforces Round #304 C(Div. 2)(模拟)
题目链接: http://codeforces.com/problemset/problem/546/C 题意: 总共有n张牌,1手中有k1张分别为:x1, x2, x3, ..xk1,2手中有k2张 ...
- cascade 介绍与用法 ( oracle)
级联删除,比如你删除某个表的时候后面加这个关键字,会在删除这个表的同时删除和该表有关系的其他对象 1.级联删除表中的信息,当表A中的字段引用了表B中的字段时,一旦删除B中该字段的信息,表A的信息也自动 ...
- yii2.0框架安装心得
yii2.0安装心得 能够搜索到这篇文章的朋友相信是对yii框架有兴趣的,但是我不得不吐槽的是,这个安装过程确实让人头疼,接下来就让大家见证一下这个纠结的过程 根据官网的说法,安装这个框架需要用到co ...
- iOS开发--UIDatePicker
UIDatePicker 是一个控制器类,封装了 UIPickerView,但是他是UIControl的子类,专门用于接受日期.时间和持续时长的输入.日期选取器的各列会按照指定的风格进行自动配置,这样 ...
- Android 下拉刷新
以前旧版用的是开源的PullToRefresh第三方库,该库现在已经不再维护了: chrisbanes/Android-PullToRefreshhttps://github.com/chrisban ...
- 在ubuntu上搭建开发环境1---在windows7的基础上在安装ubuntu(双系统)
转载:http://jingyan.baidu.com/article/60ccbceb18624464cab197ea.html 当需要频繁使用ubuntu时,vmware虚拟机下运行ubuntu, ...
- 在python多进程中使用manager和Barrier
注意:Barrier是PYTHON3才有的功能,在2中无法测试. #!/usr/bin/env python # -*- coding: utf-8 -*- import multiprocessin ...
- 简简单单的一个PYTHON多进程实现
因为在作自动化部署时,希望能将多个服务分不同的批次进行发布, 同一批次的机器同时发布, 如果前面一批次出错误,后面就需要停止整 个流程. 那可以简单的用threading来实现了. thread_li ...
- c++ 左值右值 函数模板
1.先看一段代码,这就是一种函数模板的用法,但是红色的部分如果把a写成a++或者写成一个常量比如1,都是编译不过的,因为如果是a++的话,实际上首先是取得a的 值0,而0作为一个常量没有地址.写成1也 ...
- Oracle RMAN备份策略
建立增量备份:如果数据库运行于不归档模式下,只能在数据库干净关闭的情况下 ( 以 normal .immediate . transactional 方式关闭 ) 才能进行一致性的增量备份,如果数据库 ...