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. 【WXS数据类型】Number

    Number包括整数与小数. 属性: 名称 返回 说明 [Number].constructor 值为字符串“Number” 返回该类型的结构字符串 方法: 原型:[Number].toString( ...

  2. 标注点(Labeled Point)

    标注点LabeledPoint是一种带有标签(Label/Response)的本地向量,它可以是稠密或者是稀疏的.在MLlib中,标注点在监督学习算法中被使用.由于标签是用双精度浮点型来存储的,故标注 ...

  3. appcrawler遍历工具常用方法

    Usage: appcrawler [options] -a, --app <value> Android或者iOS的文件地址, 可以是网络地址, 赋值给appium的app选项 -c,  ...

  4. halcon基础应用和方法经验分享

    halcon基础应用和方法经验分享 一.Halcon软件 的安装 安装一直点下一步就好了,这个过程很简单,就不讲了 二.Halcon软件license安装 Halcon是商业视觉软件,是需要收费的,但 ...

  5. Python3.5 Keras-Theano(含其他库)windows 安装环境

    https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-4.2.0-Windows-x86.execonda --version ...

  6. CryptoZombies学习笔记——Lesson5

    chapter1:token代币 简而言之,通证就是支持交易的包含一系列规范的函数接口的一个智能合约,发币可以用ERC20标准,但是像僵尸这种非同质化代币,需要用ERC721标准 chapter2:e ...

  7. StrBlobPtr类——weak_ptr访问vector元素

    #include <iostream> #include <memory> #include <string> #include <initializer_l ...

  8. Phpcms V9导航循环下拉菜单的调用技巧

    这个方法基于PC V9官方模版中的调用方法,然后利用后台的“Phpcms V9菜单是否显示设置”控制菜单是否显示出来. 先看看最后的效果: 调用方法: <div id="navbar& ...

  9. 20172305 2018-2019-1 《Java软件结构与数据结构》第一周学习总结

    20172305 2018-2019-1 <Java软件结构与数据结构>第一周学习总结 教材学习内容总结 本周内容主要为书第一章和第二章的内容: 第一章 软件质量: 正确性(软件达到特定需 ...

  10. 20162328蔡文琛week02

    学号 20162328 <程序设计与数据结构>第2周学习总结 教材学习内容总结 这周学习了课本中的第二章内容,比起第一章,本章难度有略微底稿,从刚开始的显示字符转变为简单的加减乘除运算,经 ...