有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。
给出每个人的孩子的信息。
输出一个序列,使得每个人的孩子都比那个人后列出。
输入格式
第 1 行一个整数 n ,表示家族的人数;
接下来 n 行,第 i 行描述第 i 个人的孩子;
每行最后是 0 表示描述完毕。
每个人的编号从 1 到 n 。
输出格式
输出一个序列,使得每个人的孩子都比那个人后列出;
数据保证一定有解,如果有多解输出任意一解。
数据范围
1≤n≤100
输入样例:
5
0
4 5 1 0
1 0
5 3 0
3 0
输出样例:
2 4 5 3 1
所用数据结构为链式前向星存的边,也可以用邻接表或邻接矩阵。
#include <bits/stdc++.h>
using namespace std;
int head[1100], ans[110];
int cnt;
struct node
{
int to, ne;
} a[1010];
int vis[111];
int n;
void add(int x, int y)
{
cnt++;
a[cnt].to = y;
a[cnt].ne = head[x];
head[x] = cnt;
}
void to_sort()
{
int hh = -1, tt = 0;
for (int i = 1; i <= n; i++)
if (vis[i] == 0) ans[++hh] = i;
while (tt <= hh)
{
int temp = ans[tt];
for (int i = head[temp]; i != -1; i = a[i].ne)
{
int now = a[i].to;
vis[now]--;
if (vis[now] == 0) ans[++hh] = now;
}
tt++;
}
for (int i = 0; i <= hh; i++) cout << ans[i] << " ";
}
int main()
{
cin >> n;
memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++)
{
int x;
while (cin >> x && x)
{
add(i, x);
vis[x]++;
}
}
to_sort();
return 0;
}
给定一张 N 个点 M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。
输入格式
第一行两个整数 N,M,接下来 M 行每行两个整数 x,y,表示从 x 到 y 的一条有向边。
输出格式
输出共 N 行,表示每个点能够到达的点的数量。
数据范围
1≤N,M≤30000
输入样例:
10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9
输出样例:
1
6
3
3
2
1
1
1
1
1
#include <bits/stdc++.h>
using namespace std;
const int N = 30010;
int head[N],ans[N],vis[N];
int cnt,n,m;
bitset<N> b[N];
struct node
{
int to,ne;
}a[N];
void add(int x,int y)
{
cnt++;
a[cnt].to = y;
a[cnt].ne = head[x];
head[x] = cnt;
}
void to_sort()
{
int tt = 0,hh=-1;
for(int i=1;i<=n;i++)
if(vis[i]==0)
ans[++hh] = i;
while(tt<=hh)
{
int temp = ans[tt];
for(int i=head[temp];i!=-1;i=a[i].ne)
{
int now = a[i].to;
vis[now]--;
if(vis[now]==0)
ans[++hh] = now;
}
tt++;
}
for(int i = n-1;i>=0;i--)
{
int x = ans[i];
b[x][x] = 1;
for(int i=head[x];i!=-1;i=a[i].ne)
{
int temp = a[i].to;
b[x]=b[x]|b[temp];
}
}
for(int i=1;i<=n;i++)
{
cout <<b[i].count()<<endl;
}
}
int main()
{
cin >> n>>m;
memset(head,-1,sizeof(head));
for(int i=1;i<=m;i++)
{
int x,y;
cin >> x >>y;
add(x,y);
vis[y]++;
}
to_sort();
return 0;
}