# 1904 King's Quest

King's Quest
 Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 1045 Accepted: 329 Case Time Limit: 2000MS

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

Sample Output

Hint
This problem has huge input and output data,use scanf() and printf() instead of cin and cout to read data to avoid time limit exceed.

Source
Northeastern Europe

***********************************************************************************

***********************************************************************************

Source Code
/*

1。如果题目中给的初始匹配包含这条边 则题目给出的初始匹配就证明了这位王子的公德心
2。如果题目没有给出这条边 给出的是Ai -> Bk 由于Ai与Bk也可互访 所以存在Bj->Ai->Bk的增广路 也就是说可以建立另外一个匹配A?->Bk

1.对图进行DFS遍历 遍历中记下所有的结束时间A[i].遍历的结果是构建的一座森林W1
我们对W1中的每棵树G进行步骤2到步骤3的操作
2.改变图G中每一条边的方向 构造出新的有向图Gr
3.按照A[i]由小到大的顺序对Gr进行DFS遍历.遍历的结果是构建了新的树林W2.
W2中每棵树上的顶点构成了有向图的极大强连通分支

*/
#include <vector>
#include <algorithm>
using namespace std;

const int N = 2010;
int nv;
int go[N], back[N];
int scc[N];
bool chk[N];
bool love[N][N];

void DFS(int x) {
int i;
chk[x] = 1;
for(i = 0; i < head[x].size(); ++i) {
if(!chk[j])
DFS(j);
}
S.push_back(x); //入栈
}

void DFS2(int x, int id) {
int y = go[x], i;
chk[y] = 1;
scc[x] = id; //标记连通分支
for(i = 0; i < head2[y].size(); ++i) {
if(!chk[j])
}
}

int main() {
scanf("%d", &nv);
int i, t, u, j;
for(i = 0; i < nv; ++i) {
scanf("%d", &t);
while(t--) {
scanf("%d", &u);
love[i][u-1] = 1;
}
}
for(i = 0; i < nv; ++i) {
scanf("%d", &t);
go[i] = t-1;
back[t-1] = i;
}

memset(chk, 0, sizeof(chk));
for(i = 0; i < nv; ++i) if(!chk[i]) {
DFS(i); //对王子作DFS 确定i到达的点
}

memset(chk, 0, sizeof(chk));
int sccId = 0;
for(i = S.size()-1; i >= 0; --i) {
int j = S[i];
if(!chk[go[j]]) {
DFS2(j, sccId);
//再对公主做DFS 确定连通分支(对王子和对公主其实是一样的 写法有点不同而已:)
sccId++;
}
}

for(i = 0; i < nv; ++i) {
vector<int> ans;
for(j = 0; j < nv; ++j) if(love[i][j]) {
if(scc[i] == scc[back[j]])
ans.push_back(j);
}
sort(ans.begin(), ans.end());
printf("%d", ans.size());
for(j = 0; j < ans.size(); ++j)
printf(" %d", ans[j]+1);
printf("/n");
}

return 0;
}
2 1 2
2 1 2
1 3
1 4

4
2 1 2
2 1 2
2 2 3
2 3 4
1 2 3 4

• 本文已收录于以下专栏：

举报原因： 您举报文章：1904 King's Quest 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)