POJ:1904-King's Quest
King’s Quest
Time limit15000 ms
Case time limit2000 ms
Memory limit65536 kB
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个姑娘,每个王子喜欢多个姑娘,巫师按照王子的意愿安排了一份最好的结婚名单,问你王子和哪些姑娘配对其他为王子都可以和自己喜欢的姑娘配对,都能得到最好的结婚名单。
- 刚开始读题读到一半以为是一个二分匹配问题,结果题目上直接给出了一个完美匹配,然后想了下,发现,一个国王能够生2000个儿子也是很牛皮的了,其实要王子选了姑娘其他王子也能选到自己喜欢的姑娘,那就是王子喜欢所有的姑娘,那么大家怎么选都是开心的了,能选到自己喜欢的。但是肯定不可能这么完美啊,但假如一个王子喜欢两个姑娘,他娶了其中一个姑娘,另一个王子也喜欢这两个姑娘,他娶了另一个姑娘,那他们换妻换到的也都是自己喜欢的姑娘。所以就可以按照这个关系建图,如果可以形成连通图那么大家可以随便交换姑娘(但是要注意交换的也要是自己喜欢的),但是肯定可以交换到在联通图中自己喜欢的姑娘。然后跑tarjan就可以了。
- 注意在一个联通图中的姑娘可能并不是都是自己喜欢的,还有就是要将姑娘的编号和王子的编号区分开,可以加一个2000以上的数给姑娘,这个题给了15S的时间,但是还是很容易超时,可以选择使用空间换时间的方法,直接用矩阵存关系。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
using namespace std;
const int maxn = 6e3+100;
vector <int> ve[maxn],shrink[maxn],ans[maxn];//注意使用vector的清空的时候可以在使用完之后就立即清空节省时间
int low[maxn],dfn[maxn],n,num,tot;
bool vis[maxn],maps[maxn][maxn];
stack<int> st;
void init()//初始化
{
while(!st.empty())
st.pop();
num = tot = 0;
memset(vis,0,sizeof(vis));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(maps,0,sizeof(maps));
for(int i=1; i<=n; i++)
{
int m;
scanf("%d",&m);
while(m--)
{
int to;
scanf("%d",&to);
to += 2020;
maps[i][to] = true;
ve[i].push_back(to);
}
}
for(int i=1; i<=n; i++)
{
int to;
scanf("%d",&to);
to += 2020;
ve[to].push_back(i);
}
}
void tarjan(int x)//将按照关系建的图缩点
{
dfn[x] = low[x] = ++tot;
st.push(x);
vis[x] = true;
for(int i=0; i<ve[x].size(); i++)
{
int v = ve[x][i];
if(!dfn[v])
{
tarjan(v);
low[x] = min(low[x],low[v]);
}
else if(vis[v])
low[x] = min(low[x],dfn[v]);
}
if(low[x] == dfn[x])
{
while(1)
{
int now = st.top();
st.pop();
vis[now] = false;
shrink[num].push_back(now);
if(now == x)
break;
}
num++;
}
}
void get_ans()
{
vector <int> m,w;
for(int i=0; i<num; i++)
{
m.clear();
w.clear();
for(int j=0; j<shrink[i].size(); j++)
{
int v = shrink[i][j];
if(v <= 2000)
m.push_back(v);
else
w.push_back(v);
}
sort(w.begin(),w.end());//要对姑娘排序,要求是按照升序输出
for(int i=0;i<m.size();i++)
{
int u = m[i];
for(int j=0;j<w.size();j++)
{
int v = w[j];
if(maps[u][v])
ans[m[i]].push_back(w[j]);
}
}
shrink[i].clear();
}
for(int i=1;i<=n;i++)
{
printf("%d ",ans[i].size());
for(int j=0;j<ans[i].size();j++)
{
int v = ans[i][j];
printf("%d ",v-2020);
}
ans[i].clear();
ve[i].clear();
printf("\n");
}
}
int main()
{
while(scanf("%d",&n) != EOF)
{
init();
for(int i=1; i<=n; i++)//跑tarjan缩点
if(!dfn[i])
tarjan(i);
get_ans();
}
return 0;
}
POJ:1904-King's Quest的更多相关文章
- POJ 1904 King's Quest tarjan
King's Quest 题目连接: http://poj.org/problem?id=1904 Description Once upon a time there lived a king an ...
- poj 1904 King's Quest
King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每 ...
- POJ 1904 King's Quest(SCC的巧妙应用,思维题!!!,经典题)
King's Quest Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 10305 Accepted: 3798 Ca ...
- POJ 1904 King's Quest ★(强连通分量:可行完美匹配边)
题意 有n个女生和n个男生,给定一些关系表示男生喜欢女生(即两个人可以结婚),再给定一个初始匹配,表示这个男生和哪个女生结婚,初始匹配必定是合法的.求每个男生可以和哪几个女生可以结婚且能与所有人不发生 ...
- Poj 1904 King's Quest 强连通分量
题目链接: http://poj.org/problem?id=1904 题意: 有n个王子和n个公主,王子只能娶自己心仪的公主(一个王子可能会有多个心仪的公主),现已给出一个完美匹配,问每个王子都可 ...
- POJ 1904 King's Quest 强联通分量+输入输出外挂
题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...
- POJ 1904 King's Quest (强连通分量+完美匹配)
<题目链接> 题目大意: 有n个王子,每个王子都有k个喜欢的妹子,每个王子只能和喜欢的妹子结婚,大臣给出一个匹配表,每个王子都和一个妹子结婚,但是国王不满意,他要求大臣给他另一个表,每个王 ...
- POJ 1904 King's Quest(强连通图)题解
题意:n个王子有自己喜欢的ki个公主,有n个公主,每个王子只能娶一个自己喜欢的公主且不能绿别的王子.现在给你一种王子娶公主的方案,并且保证这种方案是正确的.请你给出,每个王子能娶哪些公主,要求娶这些公 ...
- 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 ...
随机推荐
- C8051开发环境
1 keilC51 2 Silicon Laboratories C8051Fxxx uVision Driver_4 C:\Keil9 3 Silicon Laboratories Configu ...
- 类成员函数的重载、覆盖和隐藏区别 (C++)
这是本人第一次写博客,主要是想记录自己的学习过程.心得体会,一是可以方便以后回顾相关知识,二是可以与大家相互学习交流. 关于C++中类成员函数的重载.覆盖和隐藏区别,第一次看到这个问题是在准备找工作的 ...
- 自定义Spring Security的身份验证失败处理
1.概述 在本快速教程中,我们将演示如何在Spring Boot应用程序中自定义Spring Security的身份验证失败处理.目标是使用表单登录方法对用户进行身份验证. 2.认证和授权(Authe ...
- 洪水 Pow
Description AKD市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD市全被水淹没了.Blue Mary,AKD市的市长,召集了他的所有顾问(包括你)参加一个紧急会议.经过细致的商 ...
- javascript 关于hashtable
javascript 实现HashTable(哈希表) 一.javascript哈希表简介 javascript里面是没有哈希表的,一直在java,C#中有时候用到了这一种数据结构,javascrip ...
- 【踩坑】spring每次请求后session不一样导致无法在服务器保存信息
根据网上的资料,若想在服务器用session保存一些信息,方法如下: public Xclass Xmethod(HttpServletRequest request, HttpSession ses ...
- 【持续更新】Spring相关
什么是IoC 什么是AoP Bean的实例化方法--3种 Bean的作用域--常用2种 Bean的生命周期 Bean的装配方式 基于xml的2种装配方式 基于Annotaton的装配方式
- spring boot + spring data jpa
Spring Data Repository的核心接口是Repository(好像也没什么好惊讶的).这个接口需要领域类(Domain Class)跟领域类的ID类型作为参数.这个接口主要是让你能知道 ...
- IOS使用固定定位遇到的问题
近日需要实现移动端页面额外功能按钮,即点击加号弹出点赞与留言功能,通常这个按钮都会固定于页面的右下角,首先就想到使用固定定位来实现. 但是在测试时我们发现,在IOS中,当系统键盘弹出时,fixed会失 ...
- .Net平台互操作技术:01. 主要问题
在.Net平台进行程序设计时,经常遇到基于Native C++,已经开发出很多类库,而现在需要用C#语言调用Native C++类库.这种情况在金融公司的量化投资部门经常发生.原因是,金融业务系统的对 ...