题目描述
FJ的牛奶生产和运输是一个复杂的过程,他用挤奶器给他的那么多头奶牛挤奶然后流入管道。
每一个管道把一台挤奶器和一个可能连有一台或多台挤奶器的接口连接起来(这样几个管道里的牛奶就汇合了)。然后牛奶流入附加管道(连在各个接口之间的管道)直到流到中央管道,通向储存室。 然后这些牛奶又经历一个逆向的过程通过管道分流到各个牛奶桶,最后被运至市场。
FJ发现对于牛奶来说有一种最多的方式从一个接口流到另一个接口。并且由于FJ是一个高效率的人,他需要确保每一个管道都有牛奶经过,也就是说,没有多余的管道。
如果我们把每个挤奶机、接口和奶罐都看成一个节点,就共有 N 个节点,输入有序的节点对A_i和B_i,代表牛奶从A_i节点流到B_i节点,如果没有相对应的父节点,那就说明这是一个挤奶器,同样的如果没有对应的尾节点,则这是一个奶罐。
FJ把这些节点编号为 1..N,这样表示牛奶只能从编号较小节点流到编号较大节点。也就是说有N-1个管道。
这几天巧克力牛奶的需求量激增,所以FJ想要在某一个接口处安装一个巧克力混合器以得到巧克力牛奶,为了节约,FJ只买了一个巧克力混合器。所以他想把这个东西放到一个所有牛奶都能经过的接口,事实上,有这种接口存在。
编程帮助FJ找到这样的节点(注意:不能把巧克力混合器放在挤奶机里)。
例如:这样的情况:
一看就知道,在6或者7可以装巧克力混合器。
输入
第一行:一个整数N;
第2..N行 :第i+1行用两个整数A_i 和 B_i,表示第i个管道的两端;
输出
若干行,升序输出每一个可以安装混合器的节点。
样例输入
9
1 4
3 5
2 4
5 6
6 7
7 8
4 6
7 9
样例输出
6
7
提示
【数据规模】
对于40%的数据: 2≤N≤250;
对于50%的数据: 2≤N≤6,000;
对于100%的数据:2≤N≤100,000;1≤A_i<B_i≤N;
Code:
#if 0
7
1 2
2 3
3 4
4 5
5 6
5 7
#endif
#include <iostream>
#include <vector>
#include <queue>
#define SIZE 100001
using namespace std;
vector<int> v[SIZE];
queue<int> q;
int degree[SIZE], c[SIZE];
int main(void)
{
int n, x, y, i, temp, temp2, tot = 0;
scanf("%d", &n);
for (i = 1; i < n; ++i)
{
scanf("%d%d", &x, &y);
v[x].push_back(y);
++degree[y];
}
for (i = 1; i < n; i++)
{
if (!degree[i])
{
degree[i] = -1;
c[i] = 1;
++tot;
q.push(i);
}
}
while (!q.empty())
{
temp = q.front();
q.pop();
if ((c[temp] == tot) && (v[temp].size() > 1))
{
continue;
}
for (i = 0; i < v[temp].size(); ++i)
{
temp2 = v[temp][i];
--degree[temp2];
c[temp2] += c[temp];
if (!degree[temp2])
{
q.push(temp2);
}
}
}
for (i = 1; i <= n; i++)
{
if ((c[i] == tot) && (degree[i] != -1))
{
printf("%d\n", i);
}
}
return 0;
}