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


解题心得:

  1. 题意就是有n个王子,n个姑娘,每个王子喜欢多个姑娘,巫师按照王子的意愿安排了一份最好的结婚名单,问你王子和哪些姑娘配对其他为王子都可以和自己喜欢的姑娘配对,都能得到最好的结婚名单。
  2. 刚开始读题读到一半以为是一个二分匹配问题,结果题目上直接给出了一个完美匹配,然后想了下,发现,一个国王能够生2000个儿子也是很牛皮的了,其实要王子选了姑娘其他王子也能选到自己喜欢的姑娘,那就是王子喜欢所有的姑娘,那么大家怎么选都是开心的了,能选到自己喜欢的。但是肯定不可能这么完美啊,但假如一个王子喜欢两个姑娘,他娶了其中一个姑娘,另一个王子也喜欢这两个姑娘,他娶了另一个姑娘,那他们换妻换到的也都是自己喜欢的姑娘。所以就可以按照这个关系建图,如果可以形成连通图那么大家可以随便交换姑娘(但是要注意交换的也要是自己喜欢的),但是肯定可以交换到在联通图中自己喜欢的姑娘。然后跑tarjan就可以了。
  3. 注意在一个联通图中的姑娘可能并不是都是自己喜欢的,还有就是要将姑娘的编号和王子的编号区分开,可以加一个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的更多相关文章

  1. 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 ...

  2. poj 1904 King's Quest

    King's Quest 题意:有N个王子和N个妹子;(1 <= N <= 2000)第i个王子喜欢Ki个妹子:(详见sample)题给一个完美匹配,即每一个王子和喜欢的一个妹子结婚:问每 ...

  3. POJ 1904 King's Quest(SCC的巧妙应用,思维题!!!,经典题)

    King's Quest Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 10305   Accepted: 3798 Ca ...

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

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

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

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

  6. POJ 1904 King's Quest 强联通分量+输入输出外挂

    题意:国王有n个儿子,现在这n个儿子要在n个女孩里选择自己喜欢的,有的儿子可能喜欢多个,最后国王的向导给出他一个匹配.匹配有n个数,代表某个儿子和哪个女孩可以结婚.已知这些条件,要你找出每个儿子可以和 ...

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

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

  8. POJ 1904 King's Quest(强连通图)题解

    题意:n个王子有自己喜欢的ki个公主,有n个公主,每个王子只能娶一个自己喜欢的公主且不能绿别的王子.现在给你一种王子娶公主的方案,并且保证这种方案是正确的.请你给出,每个王子能娶哪些公主,要求娶这些公 ...

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

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

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

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

随机推荐

  1. 使用docker save load 的时候的一个小问题

    当你使用docker save image_id > aa.tar ; 然后再使用 docker load < aa.tar 时, 你会发现此时导入的镜像的repository和 tag ...

  2. 大都市 meg

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景. 昔日,乡下有依次编号为1.. ...

  3. 《C#高效编程》读书笔记01-使用属性而不是可访问的数据成员

    在需求变更中,属性比数据成员更容易修改,例:客户对象不该与空白名称,若你使用公有属性封装Name,那么现在修改一处,而数据成员则可能要修改多处 public class Customer { priv ...

  4. Intellij idea 创建JAVA项目

    1. 打开软件,new一个project的java项目 2. 点击下一步,此界面可通过模板生成项目,如下图 3. 填写项目名称和项目源码的保存路径,如下图 4. 点击 Finish 完成按钮即可,项目 ...

  5. Kendo UI 模板概述

    Kendo UI 模板概述 Kendo UI 框架提供了一个易用,高性能的 JavaScript 模板引擎.通过模板可以创建一个 HTML 片段然后可以和 JavaScript 数据合并成最终的 HT ...

  6. C++ error:Debug Assertion Failed.Expression:_BLOCK_TYPE_IS_VALID(phead->nBlock)

    Debug Assertion Failed.Expression:_BLOCK_TYPE_IS_VALID(phead->nBlockUse) 关于上面这个错误,我在上一篇文章中的程序遇到过了 ...

  7. ios 设置导航栏背景色

    //设置导航栏背景色 如果上面的不好用 就用下面的 [self.navigationController.navigationBar setBackgroundImage:[UIImage image ...

  8. linux下设置SSH无密码登录

    ssh配置 主机A:10.0.5.199 主机B:10.0.5.198 需要配置主机A无密码登录主机A,主机B 先确保所有主机的防火墙处于关闭状态. 在主机A上执行如下: 1. $cd ~/.ssh ...

  9. mysql-单表操作

    mySql单表操作主要有一下内容: 1.查询:查询又分为几种,范围查询,模糊查询.空值查询.多条件查询 查询的语句格式为:SELECT 字段 1,字段 2,字段 3...FROM 表名 WHERE 条 ...

  10. tpcc-mysql的安装和使用

    tpcc-mysql介绍 TPC(Tracsaction Processing Performance Council) 事务处理性能协会是一个评价大型数据库系统软硬件性能的非盈利的组织,TPC-C是 ...