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 ...
随机推荐
- Ubuntu系统修改服务器的静态ip地址
Ubuntu 16.04 #vi /etc/network/interfaces auto lo iface lo inet loopback auto ens3 iface ens3 inet st ...
- F. Clique in the Divisibility Graph DP
http://codeforces.com/contest/566/problem/F F. Clique in the Divisibility Graph time limit per test ...
- 牛客网Java刷题知识点之为什么static成员方法不能是抽象方法,其必须实现
不多说,直接上干货! static修饰的方法我们称之为静态方法,我们通过类名对其进行直接调用.由于它在类加载的时候就存在了,它不依赖于任何实例,所以static方法必须实现,也就是说它不能是抽象方法.
- SyntaxError: Use of const in strict mode.
具体报错console c:\Users\Administrator\WebstormProjects\blogtest\node_modules\connect-mongo\src\index.js ...
- Kendo MVVM 数据绑定(一) attr
Kendo MVVM 数据绑定(一) attr Kendo UI MVVM 数据绑定支持的绑定属性有 attr, checked, click, custom , disabled,enabled, ...
- JavaScript_7_运算符
1. 算术运算符 2. 赋值运算符 3. 用于字符串的+运算 如果把字符串与数字相加,结果将成为字符串 <!DOCTYPE html> <html> <head> ...
- 2017.10.1 QBXT 模拟赛
题目链接 T1 枚举右端点,前缀和优化.对于当前点x,答案为 sum[x][r]-sum[x][l-1]-(sum[z][r]-sum[z][l-1]) 整理为 sum[x][r]-sum[z][r] ...
- Java异常之RuntimeException
人生不如意十有八九.在打Core Java里面的例子的时候总是一遍就过,但是实际上只要是自己想着动手去打造自己想要的东西,异常的状况也是十有八九的. 在Java中会使用异常处理的错误捕获机制处理这些异 ...
- Java的数组与内存控制
1 数组基础 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成.其中,每一个数据称作一个数组元素(item),每个数组元素可以通过一个下标/索引来(index)访问它们. 数组 ...
- 【转】iOS开发-文件管理(一)
iOS开发-文件管理(一) 一.iOS中的沙盒机制 iOS应用程序只能对自己创建的文件系统读取文件,这个独立.封闭.安全的空间,叫做沙盒.它一般存放着程序包文件(可执行文件).图片.音频.视频.pli ...