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. sql server 2008出现远程过程调用失败

    sql server  2008出现远程过程调用失败解决方式有下面几种: 1.依照网上说的方法.是由于装了vs 2012或是vs2013或是vs2015等高版本号时.安装了Microsoft SQL ...

  2. UVA - 11354Bond最小生成树,LCA寻找近期公共祖先

    看懂题目意思.他的意思是求将全部的城市走一遍,危急度最小.而且给 你两个s,t后让你求在走的时候,从s到t过程中危急度最大的值,并输出它, 然后就是怎样攻克了,这个题目能够说简单,也能够说难 通过思考 ...

  3. Net is as typeof 运行运算符详解 net 自定义泛型那点事

    Net is as typeof 运行运算符详解   概述 在了解运行运算符的前提我们需要了解什么是RTTI ,在任何一门面向对象的语言中,都有RTTI这个概念(即 运行时). RTTI(Run-Ti ...

  4. caffe搭建--caffe在invidia+cpu 酷睿2Q9300 + ubuntu16.04.2上面的安装和编译过程

    本文原创,转载请注明出处. ------------------------------------------------分割线-------------------------------- 概要 ...

  5. java arraylist源码记录

    1. ArrayList 实现了RandomAccess接口, RandomAccess接口用于标记是否可以随机访问 2. 继承了AbstractList类, 因此获取了modcount , modc ...

  6. oracle死锁的检测查询及处理

    -- 死锁查询语句 SELECT bs.username "Blocking User", bs.username "DB User", ws.username ...

  7. Oracle 索引 简单介绍

    1 索引的创建语法: CREATE UNIUQE | BITMAP INDEX <schema>.<index_name>       ON <schema>.&l ...

  8. Linux快捷键和vim快捷键

    系统下常用快捷键   ctrl+左右键      在单词之间跳转 Ctrl + a            光标移动到行首(ahead of line),相当于通常的Home键 Ctrl + e     ...

  9. Nmap扫描教程之基础扫描具体解释

    Nmap扫描教程之基础扫描具体解释 Nmap扫描基础扫描 当用户对Nmap工具了解后,就可以使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具能够分别对主机.port.版本号.操作系统等实施扫 ...

  10. codevs1032

    题目地址:http://codevs.cn/problem/1032/ 分析: 题目数据有错.这题过不了才正常. 我调了非常久可是就是有两个点过不去.于是我把数据下了下来,找到WA的第五个点和第七个点 ...