Skip to content

13010: 【原3010】Complicated Buttons

题目

题目描述

author: zdq 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/3010

Description

凯恩在遗迹探险时遇到了n个按钮,刚开始所有按钮都处于开状态,凯恩的经验告诉他把所有按钮都关上会有“好事”发生,可是有些按钮按下时会让其他一些已经闭合的按钮弹开,经过凯恩研究,每个按钮都对应着一个固定的弹开集合,这个按钮按下时,弹开集合中所有的按钮都会变为开状态。现在小k想知道是否能让所有的按钮变为闭状态。如果能,打印最少步数以及方案,否则,打印“no solution”。

Input Format

第一行一个整数n,表示n个按钮。

接下来n行,表示编号为1到n个按钮的弹开集合。

格式为 mi B1 B2 B3 … Bmi

表示编号为i的按钮按下,会让编号为B1 B2 B3… Bmi的按钮弹开(注:其中不会出现重复)。

1 <= n <= 30000
记 M = m1+m2+…+mn,
0 <= M <= 1000000, 对于70%的数据n <= 300

Output Format

如果无解,输出”no solution”。

否则,第一行输出最少步数ans,第二行输出用空格分开的ans个数,表示按顺序按下编号为这些数的按钮就可以解决。

如果有多种方案,输出字典序最小的方案。

Sample Input

6
2 2 3
0
2 4 5
0
0
0

Sample Output

6
1 2 3 4 5 6

yyong119's solution

#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#define MAX_N 30010
using namespace std;
int n, m, cnt;
int in[MAX_N], ans[MAX_N];
vector<int> link_node[MAX_N];
priority_queue<int, vector<int>, greater<int> > q;
inline int read() {
    char ch = getchar(); int res = 0, flag = 1;
    while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    if (ch == '-') flag = -1, ch = getchar();
    while (ch >= '0' && ch <= '9')
        res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar();
    return res * flag;
}
int main() {
    n = read();
    for (register int i = 1; i <= n; ++i) {
        m = read();
        for (register int j = 0; j < m; ++j) {
            int tmp = read();
            link_node[i].push_back(tmp);
            ++in[tmp];
        }
    }
    for (register int i = 1; i <= n; ++i)
        if (!in[i]) q.push(i);
    while (!q.empty()) {
        int cur = q.top(); q.pop();
        ans[++cnt] = cur;
        for (register int i = 0; i < link_node[cur].size(); ++i) {
            int tmp = link_node[cur][i];
            if (!(--in[tmp]))
                q.push(tmp);
        }
    }
    if (cnt != n) printf("no solution");
    else {
        printf("%d\n", n);
        for (register int i = 1; i <= n; ++i)
            printf("%d ", ans[i]);
    }
    return 0;
}