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. 我的Android进阶之旅------&gt;怎样解决Android 5.0中出现的警告: Service Intent must be explicit:

    我的Android进阶之旅-->怎样解决Android 5.0中出现的警告: java.lang.IllegalArgumentException: Service Intent must be ...

  2. LINUX下GDB反汇编和调试

    Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数.而Windows下却是相反. 1. 基本操作指令 简单的操作数类型说明.一般有三种. (1)马上数操作数 ...

  3. Android开发——进程间通信之AIDL(二)

    0.  前言 不论是Android还是其它操作系统.都会有自己的IPC机制.所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是非常不同的概念,线程是CP ...

  4. yum安装zabbix监控

    公司的服务器由于没有监控软件监控,最感觉不安全,就开始研究zabbix的安装,最后找到一个最简单的安装方法,在这里记录一下,方便以后的查阅 1.安装zabbix官方的软件配置仓库 rpm -ivh h ...

  5. 【转】Linux上的free命令详解

    解释一下Linux上free命令的输出.默认输出是KB,可以用free -m则输出是MB 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO ...

  6. AsyncTask源代码解析

    快要毕业了.近期在阿里巴巴校园招聘面试,一面过了,感觉挺轻松,可能是运气好.面试官感觉比我腼腆一些.我俩从android绕到了spring mvc 到数据库悲观锁 到linux 然后又会到了andro ...

  7. 运维基础-IO 管道

    什么是文件描述符FD或者文件句柄? 通过构建一个带有编号标记的通道(文件描述符)的进程结构来管理打开的文件.今晨连接到文件,从而达到这些文件所代表的的数据内容或者设备.通过使用通道0.1.2(称为标准 ...

  8. MVC准备工作

    准备工作 打开VS创建一个ASP.NET MVC空项目,在http://www.asp.net/mvc/overview/getting-started/introduction/getting-st ...

  9. 网络爬虫(蜘蛛)Scrapy,Python安装!

    Scrapy,Python安装.使用! 1.下载安装Python2.7.6.由于Scrapy还不支持3.x版本号. Latest Python 2 Release - Python 2.7.6,安装时 ...

  10. 使用git checkout 指定git代码库上的指定分支

    因为曾经一直是在用svn,到狼厂,大家都用Git. 哥的开发环境:IntelliJ 说说简单的操作过程吧. 1.检出Git代码库 cd到指定文件夹 git clone http://..../andr ...