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(强连通+思维)的更多相关文章

  1. UVA1327 && POJ1904 King's Quest(tarjan+巧妙建图+强连通分量+缩点)

    UVA1327 King's Quest POJ1904 King's Quest 题意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚.现有一个匹配表,将每个王子都与一个自己 ...

  2. POJ1904 King's Quest

    King's Quest Language:Default King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submission ...

  3. POJ1904 King's Quest(完备匹配可行边:强连通分量)

    题目大概就是说给一张二分图以及它的一个完备匹配,现在问X部的各个点可以与Y部那些些点匹配,使得X部其余点都能找到完备匹配. 枚举然后匹配,当然不行,会超时. 这题的解法是,在二分图基础上建一个有向图: ...

  4. 【建模+强连通分量】POJ1904 King's Quest

    Description 一个国王有n个王子,同时有n个女孩.每个王子都有自己喜欢的若干个女孩,现给定一个合法的完备匹配(也就是一个王子娶其中一个自己喜欢女孩),求每个王子可以选择哪些女孩可以让剩下的每 ...

  5. Poj 1904 King's Quest 强连通分量

    题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...

  6. POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)

    题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...

  7. POJ 1904 King's Quest (强连通分量+完美匹配)

    <题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...

  8. POJ - 1904 King's Quest (强连通)

    题意:有N个王子,每个王子有任意个喜欢的妹子,巫师会给出一个方案:每个妹子都嫁给一个王子.但是国王希望知道:每个王子能在哪些妹子中择偶而不影响其他王子择偶. 分析:设王子为x部,妹子为y部,假设有匹配 ...

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

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

随机推荐

  1. (转)CGMA - Organic World Building in UE4: week 6

    原文:丢失,这篇是艺术家博客上发现的,小道整理笔记中,临时放于效果案例目录.     In this week we focused on creating the grass and flora t ...

  2. Memcache的客户端连接系列(一) Java

    声明:本文并非原创,转自华为云帮助中心的分布式缓存服务(Memcached)的用户指南. 关键词: Memcached  客户端 Java Java连接池 Java客户端示例 用户的弹性云服务器已安装 ...

  3. Kali渗透测试工具-nslookup

    1.交互模式 终端输入nslookup进入交互模式 (1)查询A地址记录(默认) set q=a A记录简单理解将域名转换成对应的IP地址 (2)查询mail exchanger set q=mx m ...

  4. Ext JS 6学习文档-第3章-基础组件

    Ext JS 6学习文档-第3章-基础组件 基础组件 在本章中,你将学习到一些 Ext JS 基础组件的使用.同时我们会结合所学创建一个小项目.这一章我们将学习以下知识点: 熟悉基本的组件 – 按钮, ...

  5. Alphabetic Removals(模拟水题)

    You are given a string ss consisting of nn lowercase Latin letters. Polycarp wants to remove exactly ...

  6. “Hello World!”团队第二次会议

    今天是我们团队“hello world!”团队召开的第二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 20 ...

  7. 基于NABCD评论“探路者”Alpha版作品

    1.分析 N(Need):”为了重温贪吃蛇这一经典游戏,本组的选题定为贪吃蛇游戏,并在此基础上进行了新的创新,将普通的贪吃蛇游戏改为单词版贪吃蛇.市面上的英语单词背记软件对于那些缺少英语学习兴趣.毅力 ...

  8. LintCode-8.旋转字符串

    旋转字符串 给定一个字符串和一个偏移量,根据偏移量旋转字符串(从左向右旋转) 样例 对于字符串 "abcdefg". offset=0 => "abcdefg&qu ...

  9. LintCode-532.逆序对

    逆序对 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.给你一个数组,求出这个数组中逆序对的总数. 概括:如果a[i] > a[j] 且 i < j, a[i ...

  10. 活学活用wxPython

    http://www.czug.org/python/wxpythoninaction/