POJ1904:King's Quest(强连通+思维)
King's Quest
Time Limit: 15000MS | Memory Limit: 65536K | |
Total Submissions: 10352 | Accepted: 3815 |
题目链接:http://poj.org/problem?id=1904
Description:
Once upon a time there lived a king and he had N sons. And there were N beautiful girls in the kingdom and the king knew about each of his sons which of those girls he did like. The sons of the king were young and light-headed, so it was possible for one son to like several girls.
So the king asked his wizard to find for each of his sons the girl he liked, so that he could marry her. And the king's wizard did it -- for each son the girl that he could marry was chosen, so that he liked this girl and, of course, each beautiful girl had to marry only one of the king's sons.
However, the king looked at the list and said: "I like the list you have made, but I am not completely satisfied. For each son I would like to know all the girls that he can marry. Of course, after he marries any of those girls, for each other son you must still be able to choose the girl he likes to marry."
The problem the king wanted the wizard to solve had become too hard for him. You must save wizard's head by solving this problem.
Input:
The first line of the input contains N -- the number of king's sons (1 <= N <= 2000). Next N lines for each of king's sons contain the list of the girls he likes: first Ki -- the number of those girls, and then Ki different integer numbers, ranging from 1 to N denoting the girls. The sum of all Ki does not exceed 200000.
The last line of the case contains the original list the wizard had made -- N different integer numbers: for each son the number of the girl he would marry in compliance with this list. It is guaranteed that the list is correct, that is, each son likes the girl he must marry according to this list.
Output:
Output N lines.For each king's son first print Li -- the number of different girls he likes and can marry so that after his marriage it is possible to marry each of the other king's sons. After that print Li different integer numbers denoting those girls, in ascending order.
Sample Input:
4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4
Sample Output:
2 1 2
2 1 2
1 3
1 4
题意:
有n个王子n个公主,每个王子都有其喜欢的公主,每个公主都可以接受所有王子(= =),然后起初会给你一个婚姻方案。现在让你输出每个王子所有可以结婚的对象,并且他们结婚后,不会影响其它王子的婚姻。
题解:
这还是一个挺有意思的题。因为这求的是方案数,所以二分图匹配在这里不太适用。
考虑一下一个集合,这个集合中的所有王子都喜欢这个集合中的所有公主,并且满足题中条件,那么也就是说,所有王子都是可达某个公主的。
我们来考虑一下用连通性求解,对于原先给出的匹配,我们由公主连向王子,对于所有王子喜欢的公主,就由王子连向公主。然后利用tarjan求强连通分量。对于每一个强连通分量集合中的点,都是满足条件的。因为集合中的元素都是互相可达的,王子选择了一个,不会影响另一个人的婚姻。至于这里公主向王子的连边,可以理解为“撤销操作”:当一个公主被一个王子选取过后,那么原来选择这个公主的王子就可以撤销这个操作选择其它公主。如果存在强连通分量,那么这个撤销操作是肯定可以到达另外一个公主的,当然也可能不到达,就在男生这里终止。
还需要注意的一点就是,可能集合中的某对王子、公主,可能王子本身就不喜欢那个公主,也就是本来可以的撤销操作在王子那里就终止了。这时要注意一下输出。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
using namespace std ;
typedef long long ll;
const int N = ;
int n,tot;
int head[N];
struct Edge{
int u,v,next;
}e[];
void adde(int u,int v){
e[tot].v=v;e[tot].next=head[u];head[u]=tot++;
}
vector <int> ans[N],g[N];
stack <int> s;
int T,num;
int scc[N],dfn[N],low[N],vis[N];
void Tarjan(int u){
dfn[u]=low[u]=++T;vis[u]=;
s.push(u);
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!vis[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}else if(!scc[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
num++;int now;
do{
now = s.top();s.pop();
scc[now]=num;
}while(!s.empty() && now!=u);
}
}
int main(){
while(scanf("%d",&n)!=EOF){
memset(scc,,sizeof(scc));
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
memset(head,-,sizeof(head));
for(int i=;i<=n;i++) g[i].clear(),ans[i].clear();
num=;T=;tot=;
for(int i=;i<=n;i++){
int k;
scanf("%d",&k);
for(int j=;j<=k;j++){
int l;
scanf("%d",&l);
g[i].push_back(l);
adde(i,l+n);
}
}
for(int i=;i<=n;i++){
int l;
scanf("%d",&l);
adde(l+n,i);
}
for(int i=;i<=*n;i++){
if(!vis[i]) Tarjan(i);
}
for(int i=;i<=n;i++){
for(int j=head[i];j!=-;j=e[j].next){
int v=e[j].v;v-=n;
if(scc[i]==scc[v+n]) ans[i].push_back(v);
}
}
for(int i=;i<=n;i++){
printf("%d ",(int)ans[i].size());
sort(ans[i].begin(),ans[i].end());
for(int j=;j<ans[i].size();j++){
printf("%d ",ans[i][j]);
}
printf("\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(完备匹配可行边:强连通分量)
题目大概就是说给一张二分图以及它的一个完备匹配,现在问X部的各个点可以与Y部那些些点匹配,使得X部其余点都能找到完备匹配. 枚举然后匹配,当然不行,会超时. 这题的解法是,在二分图基础上建一个有向图: ...
- 【建模+强连通分量】POJ1904 King's Quest
Description 一个国王有n个王子,同时有n个女孩.每个王子都有自己喜欢的若干个女孩,现给定一个合法的完备匹配(也就是一个王子娶其中一个自己喜欢女孩),求每个王子可以选择哪些女孩可以让剩下的每 ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
- POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...
- POJ 1904 King's Quest (强连通分量+完美匹配)
<题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...
- POJ - 1904 King's Quest (强连通)
题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...
- POJ 1904 King's Quest 强连通分量+二分图增广判定
http://www.cnblogs.com/zxndgv/archive/2011/08/06/2129333.html 这位神说的很好 #include <iostream> #inc ...
随机推荐
- C 数数位 while循环
#include <stdio.h> int main(int argc, char **argv) { //定义两个变量 x n 把n初始化 int x; int n=0; //输入x ...
- ubuntu 执行Python脚本出现: /usr/bin/env: ‘python\r’: No such file or directory
原因: #!/usr/bin/env python 在ubuntu会变成 #!/usr/bin/env python\r 而\r 会被shell 当成参数 所以出现: /usr/bin/env: ‘ ...
- 孤荷凌寒自学python第八十天开始写Python的第一个爬虫10
孤荷凌寒自学python第八十天开始写Python的第一个爬虫10 (完整学习过程屏幕记录视频地址在文末) 原计划今天应当可以解决读取所有页的目录并转而取出所有新闻的功能,不过由于学习时间不够,只是进 ...
- 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...
- python3 SQLAlchemy模块使用
更详细的操作介绍:https://www.imooc.com/article/22343 定义: SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对 ...
- Python3 Tkinter-Entry
1.创建 from tkinter import * root=Tk() t1=Entry(root) t1.pack() root.mainloop() 2.绑定变量 from tkinter im ...
- js经典试题之数据类型
js经典试题之数据类型 1:输出"B" + "a" + + "B" + "a"的值: 答案:BaNaNa. 分析:因为+ ...
- js中的数组对象排序
一.普通数组排序 js中用方法sort()为数组排序.sort()方法有一个可选参数,是用来确定元素顺序的函数.如果这个参数被省略,那么数组中的元素将按照ASCII字符顺序进行排序.如: var ar ...
- Memcache+Cookie解决分布式系统共享登录状态
Memcached高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.Memcached能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等. Memc ...
- C#及时释放代码
using语句,定义一个范围,在范围结束时释放对象. 场景: 当在某个代码段中使用了类的实例,而希望无论因为什么原因,只要离开了这个代码段就自动调用这个类实例的Dispose. 要达到这样的目的,用t ...