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

时间:2021-01-22 22:31:47
King's Quest
Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 10305   Accepted: 3798
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

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

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.
 
题目意思:
国王有n个儿子,每个儿子喜欢ki个女孩,国王想让王子和他喜欢的人结婚,
就让巫师做一个列表,就是国王想知道每个王子可以和哪些女生结合且不影响其他王子也能和自己喜欢的人结婚
其实就是求王子和哪些女生结婚不影响最大匹配!!!
做法:
对每个王子喜欢的女生,王子到女孩建边
对完备匹配,女孩到王子建边
然后和王子x属于同一个SCC的且王子喜欢的女生就是王子x在不影响最大匹配的情况下,可以结婚的女生
1.为什么对完备匹配反向建边?
保证完备匹配的女生y和王子x是属于同一个SCC
2.为什么该图是二分图?
题目说n个王子,n个女生,保证每个王子都可以匹配到喜欢的女生
所以该图是二分图
且同一个SCC中王子和女生的数目是相同的!!
3.为什么王子不能选择其他SCC的女生?
反证法:如果强连通分量1中的王子选择了强连通分量2中的妹子,
那么势必强连通分量2中的一个王子无法在自己的强连通分量中找到妹子,
那么他就会去别的强连通分量找妹子,这样一直循环下去,
我们知道最终一定是经过了强连通分量1,2,x1,x2,xn,……,1,
王子们才能都找到自己的妹子,这样这些强连通分量1,2,x1,x2,xn,……,1会构成一个强连通分量,
与题设在不同强连通分量中找妹子不符
和王子的同一个SCC里面的女生,该王子都可以选择与其结婚(前提是该王子喜欢)
坑点:
1.对在同一个SCC里面的女生y,王子x不一定喜欢
2.输出的编号要升序排序
 
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<string.h>
#include<set>
#include<map>
#include<list>
#include<math.h>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long LL;
#define INF 0x7fffffff
#define me(a,x) memset(a,x,sizeof(a))
int mon1[]= {,,,,,,,,,,,,};
int mon2[]= {,,,,,,,,,,,,};
int dir[][]= {{,},{,-},{,},{-,}}; int getval()
{
int ret();
char c;
while((c=getchar())==' '||c=='\n'||c=='\r');
ret=c-'';
while((c=getchar())!=' '&&c!='\n'&&c!='\r')
ret=ret*+c-'';
return ret;
}
void out(int a)
{
if(a>)
out(a/);
putchar(a%+'');
} #define max_v 20005
int vis[max_v];
int dfn[max_v];
int low[max_v];
int color[max_v];
int stk[max_v];
vector<int> G[max_v];
int n,m;
int sig,cnt,sp; priority_queue<int,vector<int>,greater<int> > q;//优先队列 升序
void init()
{
me(vis,);
me(dfn,);
me(color,);
me(low,);
for(int i=;i<=n*;i++)
{
G[i].clear();
}
sig=;
cnt=;
sp=-;
} void tarjan(int u)
{
vis[u]=;
dfn[u]=low[u]=cnt++;
stk[++sp]=u;
for(int j=;j<G[u].size();j++)
{
int v=G[u][j];
if(vis[v]==)
tarjan(v);
if(vis[v]==)
low[u]=min(low[v],low[u]);
}
if(low[u]==dfn[u])
{
sig++;
do
{
color[stk[sp]]=sig;
vis[stk[sp]]=-;
}while(stk[sp--]!=u);
}
}
int main()
{
int x,y;
while(~scanf("%d",&n))
{
init();
for(int i=;i<=n;i++)
{
m=getval();//输入外挂
for(int j=;j<=m;j++)
{
y=getval();
y+=n;
if(count(G[i].begin(),G[i].end(),y)==)
G[i].push_back(y);
}
}
for(int i=;i<=n;i++)
{
x=getval();
x+=n;
if(count(G[x].begin(),G[x].end(),i)==)
G[x].push_back(i);
}
for(int i=;i<=n+n;i++)
{
if(vis[i]==)
tarjan(i);
}
int sum=;
for(int i=;i<=n;i++)
{
sum=;
for(int j=;j<G[i].size();j++)//只考虑王子i喜欢的女生
{
if(color[i]==color[G[i][j]])//颜色相同代表属于同一个SCC
{
sum++;
q.push(G[i][j]-n);
}
}
out(sum);
while(!q.empty())
{
printf(" ");
out(q.top());//输出外挂
q.pop();
}
printf("\n");
}
}
return ;
} /*
题目意思:
国王有n个儿子,每个儿子喜欢ki个女孩,国王想让王子和他喜欢的人结婚,
就让巫师做一个列表,就是国王想知道每个王子可以和哪些女生结合且不影响其他王子也能和自己喜欢的人结婚
其实就是求王子和哪些女生结婚不影响最大匹配!!! 做法:
对每个王子喜欢的女生,王子到女孩建边
对完备匹配,女孩到王子建边
然后和王子x属于同一个SCC的且王子喜欢的女生就是王子x在不影响最大匹配的情况下,可以结婚的女生 1.为什么对完备匹配反向建边?
保证完备匹配的女生y和王子x是属于同一个SCC 2.为什么该图是二分图?
题目说n个王子,n个女生,保证每个王子都可以匹配到喜欢的女生
所以该图是二分图
且同一个SCC中王子和女生的数目是相同的!! 3.为什么王子不能选择其他SCC的女生?
反证法:如果强连通分量1中的王子选择了强连通分量2中的妹子,
那么势必强连通分量2中的一个王子无法在自己的强连通分量中找到妹子,
那么他就会去别的强连通分量找妹子,这样一直循环下去,
我们知道最终一定是经过了强连通分量1,2,x1,x2,xn,……,1,
王子们才能都找到自己的妹子,这样这些强连通分量1,2,x1,x2,xn,……,1会构成一个强连通分量,
与题设在不同强连通分量中找妹子不符 和王子的同一个SCC里面的女生,该王子都可以选择与其结婚(前提是该王子喜欢) 坑点:
1.对在同一个SCC里面的女生y,王子x不一定喜欢
2.输出的编号要升序排序 */