首先感谢大佬博客的题解,拓扑排序yyds!
大佬博客
题解:
对于每一个圆筒内的球,只有上边的拿走之后才能拿走下一个,从上到下连单向边
例如1->2->3,1拿走2才能拿,2拿走之后3才能拿
对于所有圆筒,最后可以构建一个有向图,如果出现环的话,肯定不能满足题目要求
例如1->2->3->1,1拿走2才能拿走,2拿走3才能拿走,3拿走1才能拿走,这就矛盾了
对于2n个点,拿n次才能恰好拿完,如果出现环的情况,拓扑排序的答案必定不是n
代码如下:
int h[N], ne[2 * N], e[2 * N], in[2 * N], idx;
void add(int a, int b)
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int main ()
{
memset(h, -1, sizeof h);
int n, m; scanf("%d%d", &n, &m);
while (m -- )
{
int k, a; scanf("%d", &k);
k --; scanf("%d", &a);
while (k -- )
{
int b; scanf("%d", &b);
add(a, b);
in[b] ++;
a = b;
}
}
queue<int> que;
for (int i = 1; i <= n; i ++ )
{
if (!in[i]) que.push(i);
}
int cnt = 0;
while (!que.empty())
{
cnt ++;
int u = que.front(); que.pop();
for (int i = h[u]; i != -1; i = ne[i])
{
int j = e[i];
in[j] --;
if (!in[j]) que.push(j);
}
}
if (cnt == n) puts("Yes");
else puts("No");
return 0;
}