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. 字符串和byte数组的相互转化

    关于byte[]数组转十六进制字符串: public static String getHexString(byte[] b) throws Exception { String result = & ...

  2. Java常用函数式接口--Consumer接口andThen()方法使用案例(二)

    Java常用函数式接口--Consumer接口使用案例

  3. WebView全面学习(二)-- Native与js双方通信

    WebView全面学习(二)-- Native与js双方通信 Native与js通信的本质 Native与js通信的核心在于WebView. 两端的通信主要还是单向的.假如要完成js->Nati ...

  4. winform ListView创建columnHeader的方法

    using System; using System.Windows.Forms; using System.Drawing; using System.Collections; namespace ...

  5. NullPointerException检测

    APET-NPE插件工作原理 android应用程序编译的过程如下: 从图中,我们可以看出,app编译大致经历了四大阶段:java source files -> .class files -& ...

  6. js构造方法

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>Java ...

  7. vijos 1320 清点人数

    背景 NK中学组织同学们去五云山寨参加社会实践活动,按惯例要乘坐火车去.由于NK中学的学生很多,在火车开之前必须清点好人数. 描述 初始时,火车上没有学生:当同学们开始上火车时,年级主任从第一节车厢出 ...

  8. Round #322 (Div. 2) 581D Three Logos (模拟)

    先枚举两个矩形,每个矩形横着放或竖着放,把一边拼起来, 如果不是拼起来有缺口就尝试用第三个矩形去补. 如果没有缺口就横着竖着枚举一下第三个矩形和合并的矩形x或y拼接. #include<bits ...

  9. ubuntu 使用apt命令时报错 E: Could not get lock /var/lib/dpkg/lock - open...

    问题描述: 刚刚安装好Ubuntu16.04.使用apt命令时,提示报错信息: abc@pc:~$ sudo apt-get install openssh-server E: Could not g ...

  10. 剑指offer22 栈的压入、弹出序列

    写的一个代码,虽然正确通过了,但我觉得会报vector越界的错误 class Solution { public: bool IsPopOrder(vector<int> pushV,ve ...