King's Quest
Time Limit: 15000MS   Memory Limit: 65536K
Total Submissions: 8311   Accepted: 3017
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
题意:一个国王有N个王子。一共有N个女孩,每个王子可以喜欢多个女孩,但只能取一个女孩。给定一个参考结婚列表,问每个王子可分别与哪几个女孩结婚。
思路:王子与女孩之间建立有向图,再根据参考结婚列表建立反向边,那么与王子处于同一个连通分量的女孩且是王子喜欢的可以和王子结婚。
附输入输出挂
#include"cstdio"
#include"cstring"
#include"algorithm"
using namespace std;
const int MAXN=;
struct Edge{
int to,next;
}es[];
int V;
void Scan(int &val)
{
char ch;
int x=;
bool flag=true;
ch=getchar();
if(ch=='-') flag=false;
else if(''<=ch&&ch<='') x=(ch-'');
while((ch=getchar())&&''<=ch&&ch<='')
x=x*+ch-'';
val=(flag==true)?x:-x;
}
void Print(int x)
{
if(x>) Print(x/);
putchar(x%+'');
}
int head[MAXN],tot;
void add_edge(int u,int v)
{
es[tot].to=v;
es[tot].next=head[u];
head[u]=tot++;
}
int index;
int dfn[MAXN],low[MAXN];
int stack[MAXN],top;
int cpnt[MAXN],cnt;
bool instack[MAXN];
void tarjan(int u)
{
instack[u]=true;
stack[top++]=u;
dfn[u]=low[u]=++index;
for(int i=head[u];i!=-;i=es[i].next)
{
int v=es[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
int v;
cnt++;
do{
v=stack[--top];
instack[v]=false;
cpnt[v]=cnt;
}while(u!=v);
}
}
int ans[MAXN];
void solve()
{
memset(ans,,sizeof(ans));
for(int i=;i<=V+V;i++)
if(!dfn[i]) tarjan(i); for(int i=;i<=V;i++)
{
int counter=;
for(int j=head[i];j!=-;j=es[j].next)
{
int v=es[j].to;
if(cpnt[v]==cpnt[i]) ans[counter++]=v-V;
}
sort(ans,ans+counter);
Print(counter);
for(int j=;j<counter;j++) putchar(' '),Print(ans[j]);
putchar('\n');
}
} int main()
{
while(scanf("%d",&V)!=EOF)
{
tot=index=top=cnt=;
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(instack,false,sizeof(instack));
memset(cpnt,,sizeof(cpnt));
for(int i=;i<=V;i++)
{
int k;
Scan(k);
while(k--)
{
int v;
Scan(v);
add_edge(i,V+v);
}
}
for(int i=;i<=V;i++)
{
int v;
Scan(v);
add_edge(V+v,i);
}
solve();
}
return ;
}
kosaraju算法——有向图缩点利器
#include"cstdio"
#include"cstring"
#include"algorithm"
#include"vector"
using namespace std;
const int MAXN=;
vector<int> G[MAXN];
vector<int> rG[MAXN];
vector<int> vs;
int V,E;
void add_edge(int u,int v)
{
G[u].push_back(v);
rG[v].push_back(u);
}
int vis[MAXN];
int cpnt[MAXN];
void dfs(int u)
{
vis[u]=;
for(int i=;i<G[u].size();i++)
if(!vis[G[u][i]]) dfs(G[u][i]);
vs.push_back(u);
}
void rdfs(int u,int k)
{
vis[u]=;
cpnt[u]=k;
for(int i=;i<rG[u].size();i++)
if(!vis[rG[u][i]]) rdfs(rG[u][i],k);
}
void scc()
{
vs.clear();
memset(vis,,sizeof(vis));
for(int i=;i<=V+V;i++)
if(!vis[i]) dfs(i);
memset(vis,,sizeof(vis));
int k=;
for(int i=vs.size()-;i>=;i--)
if(!vis[vs[i]]) rdfs(vs[i],k++);
}
int ans[MAXN];
void solve()
{
memset(ans,,sizeof(ans));
scc();
for(int i=;i<=V;i++)
{
int counter=;
for(int j=;j<G[i].size();j++)
{
int v=G[i][j];
if(cpnt[i]==cpnt[v]) ans[counter++]=v-V;
}
sort(ans,ans+counter);
printf("%d",counter);
for(int i=;i<counter;i++) printf(" %d",ans[i]);
printf("\n");
}
}
int main()
{
while(scanf("%d",&V)!=EOF)
{
for(int i=;i<=V+V;i++)
{
G[i].clear();
rG[i].clear();
} for(int i=;i<=V;i++)
{ int k;
scanf("%d",&k);
while(k--)
{
int v;
scanf("%d",&v);
add_edge(i,v+V);
}
}
for(int i=;i<=V;i++)
{
int v;
scanf("%d",&v);
add_edge(v+V,i);
} solve();
}
return ;
}
												

POJ1904(有向图缩点+输入输出挂参考)的更多相关文章

  1. 【输入输出挂】【Uva11462】Age Sort

    例题17  年龄排序(Age Sort, UVa 11462)照从小到大的顺序输出. [输入格式] 输入包含多组测试数据.每组数据的第一行为整数n(0<n≤2 000 000),即居民总数:下一 ...

  2. hdu 3072 有向图缩点成最小树形图计算最小权

    题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...

  3. HDU1269(有向图缩点模板题)

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. POJ2553( 有向图缩点)

    The Bottom of a Graph Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9779   Accepted:  ...

  5. POJ2186(有向图缩点)

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 28379   Accepted: 11488 De ...

  6. hdu 1827 有向图缩点看度数

    题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...

  7. HDU 4635 (完全图 和 有向图缩点)

    题目链接:HDU  4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...

  8. poj 2823 Sliding Windows (单调队列+输入输出挂)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 73426   Accepted: 20849 ...

  9. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

随机推荐

  1. javascript 判断字符串是否包换字符串

    用"ghiahgiahgia".indexOf("hg"); 返回值>=0为包含,否则就是-1(不包含)

  2. 【Scala类型系统】自身类型(self type)引用

    定义 特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>).这种特质仅仅能被混入给定类型的子类其中. 如果 ...

  3. 我猜你不会使用try-catch

    我猜你不会用try-catch,废话不说,首先看看大多数的人是怎么用的吧,或许你会躺枪哦. 请问.看到上面的代码,你的第一印象是啥.我猜你会说,"我不想看,我不想看,看不懂".事实 ...

  4. 辛星深入分析vim的自己主动补全功能以及vim的映射

    曾经对于vim的自己主动补全功能,都是须要的时候从网上下载点配置项,然后复制到自己的vimrc上去,自己也不知道是什么意思.结果发现搜索到的非常多自己主动补全的方式都非常另类,有的喜欢在补全大括号的时 ...

  5. 苦逼IT才能看懂的笑话

    这是苦逼IT才能看懂的笑话1.栈和队列的区别是啥? 吃多了拉就是队列:吃多了吐就是栈 2.世界上最遥远的距离不是生与死,而是你亲手制造的BUG就在你眼前,你却怎么都找不到她... 3.<c++程 ...

  6. Java依照List内存储的对象的某个字段进行排序

    关键点:将List内存储的对象实现Comparable类.重写它的compareTo()方法就可以 Bean: package chc; public class StuVo implements C ...

  7. 透视WPF 应用程序的利器

    当我们看到一些设计新颖的网站时,可以借助浏览器自带的Inspector 工具或插件方便的浏览网站布局结构及逻辑.如果是WPF 应用程序能否看到控件的架构方式呢?本篇将介绍两款工具Snoop 和WPF ...

  8. mongodb 安装、启动

    MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1   最近有太多的同学向我提起MongoDB,想要学习MongoDB,还不知道MongoDB到底是什么鬼,或者说,知道是数据 ...

  9. port_443

    GRC | Port Authority, for Internet Port 443 https://www.grc.com/port_443.htm

  10. Splits a tensor into sub tensors

    https://www.tensorflow.org/api_docs/python/tf/split # 'value' is a tensor with shape [5, 30] # Split ...