There is a tree of n vertices. For each vertex a list of all its successors is known (not only direct ones). It is required to restore the tree or to say there is no such tree.
The first line contains a single integer n (1 ≤ n ≤ 1000) — the number of vertices in the tree.
Each of the next n lines contains an integer ci (0 ≤ ci ≤ n) — the number of successors of vertex i, and then ci distinct integers aij(1 ≤ aij ≤ n) — the indices of successors of vertex i.
If the answer does not exist, output «NO».
Otherwise, in the first line output «YES», and then output n - 1 lines containing two integers each — indices of parent and child. Pairs (parent, child) can be output in any order.
5 4 2 3 4 5 3 3 4 5 2 4 5 1 5 0
YES 1 2 2 3 3 4 4 5
5 4 2 3 4 5 3 3 4 5 0 1 5 0
YES 1 2 2 3 2 4 4 5
3 3 2 3 1 3 3 1 2 3 1 2 3
NO
题意: 给你n 个点和他的后继元素 (不一定是他的儿子 有可能是孙子等等 ) 你的目标 就是要求出是否能够存在一棵树,然后满足给你的数据,如果满足输出这棵树,不满足输出NO 。
思路: 连一下边 可以想到用拓扑排序去处理,但是比较坑的一个点就是 如果两个元素的后继是相同的, 但是拓扑排序建出的树就不一定是 满足条件的。
样例 :
5
4 2 3 4 5
2 4 5
2 4 5
0
0
所以在用拓扑建出树之后再还原一下原本的图,看是否一样。
代码:
#include<bits/stdc++.h>
#define N 1005
using namespace std;
int inde[N];
int n;
vector< int >ve[N],tree[N],huan[N];
void dfs(int u){
int sz=ve[u].size();
for(int i=0;i<sz;i++){
int v=ve[u][i];
dfs(v);
huan[u].push_back(v);
int sz1=huan[v].size();
for(int j=0;j<sz1;j++){
huan[u].push_back(huan[v][j]);
}
}
return ;
}
int main()
{
int c,x;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&c);
while(c--){
scanf("%d",&x);
inde[x]++;
tree[i].push_back(x);
}
}
int in;
int cc=0;
for(int i=1;i<=n;i++){
if(inde[i]==0){
cc++;
in=i;
}
}
if(cc>=2||cc==0){
printf("NO\n");
return 0;
}
queue< int >que;
que.push(in);
int f=0;
int cnt=0;
while( !que.empty() ){
int u=que.front(); cnt++; que.pop();
int sz=tree[u].size();
for(int i=0;i<sz;i++){
int v=tree[u][i];
inde[v]--;
if(inde[v]==0){
que.push(v);
ve[u].push_back(v);
}
}
}
if( cnt!=n ) {
printf("NO\n");
return 0;
}
dfs(in);
/*
for(int i=1;i<=n;i++){
int sz=huan[i].size();
for(int j=0;j<sz;j++){
printf("%d ",huan[i][j]);
}
cout<<endl;
}*/
for(int i=1;i<=n;i++){
sort(tree[i].begin(),tree[i].end());
sort(huan[i].begin(),huan[i].end());
int sz=tree[i].size(); int sz1=huan[i].size();
if(sz!=sz1){
printf("NO\n");
return 0;
}
for(int j=0;j<sz;j++){
if(tree[i][j]!=huan[i][j]){
printf("NO\n");
return 0;
}
}
}
printf("YES\n");
for(int i=1;i<=n;i++){
int sz=ve[i].size();
for(int j=0;j<sz;j++){
printf("%d %d\n",i,ve[i][j]);
}
}
return 0;
}