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 ...
随机推荐
- Angular6项目搭建
参照 草根专栏- ASP.NET Core + Ng6 实战:https://v.qq.com/x/page/b076702elvw.html 安装工具: Nodejs, npm 最新版, h ...
- vim—自动缩进(编写Python脚本)
大神推荐使用vim编写Python脚本,学而时积之,不亦乐乎! 使用vim编写Python脚本的时候不能正常缩进,需要修改vimrc文件 Ubuntu系统下vimrc文件的位置: $ cd /etc/ ...
- Training Models
In this page, I am going to talk about the 'hello world' model that is linear regression and train i ...
- OSI七层协议模型及OSI参考模型中的数据封装过程
转载自:http://blog.csdn.net/qq_14935437/article/details/71081546 OSI模型,即开放式通信系统互联参考模型(Open System Inter ...
- 【转】Angular.js VS. Ember.js:谁将成为Web开发的新宠?
本文源自于Quora网站的一个问题,作者称最近一直在为一个新的Rails项目寻找一个JavaScript框架,通过筛选,最终纠结于 Angular.js和 Ember.js. 这个问题获得了大量的关注 ...
- C++标准库算法
一.只读算法 1. find() 2. count() 3. accumulate 4. equal 二.写入算法 1. fill 2. fill_n 3. copy 4. replace 5. re ...
- Thunder团队第三周 - Scrum会议2
Scrum会议2 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 胡佑蓉在拍照,所以不在照片中. 参会成员: 王航:http://www.cnblogs. ...
- A+B 输入输出练习I
while True: try: s=raw_input() a,b=s.split(' ') a,b=int(a),int(b) print a+b except EOFError: break A ...
- SpringMVC拦截器实现登录认证(转发)
感谢原作者,转发自:http://blog.csdn.net/u014427391/article/details/51419521 以Demo的形式讲诉拦截器的使用 项目结构如图: 需要的jar:有 ...
- Qt代码覆盖率code coverage(VS版)
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt代码覆盖率code coverage(VS版) 本文地址:http://techi ...