复杂的按钮
(button.pas/c/cpp)
【题目描述】
小K在遗迹探险时遇到了N个按钮,刚开始所有的按钮都处于开状态,小K的经验告诉他把所有的按钮都关上会有“好事”发生,可是有些按钮按下时会让其他一些已经闭合的按钮弹开。经过研究,每个按钮都对应着一个固定的弹开集合,这个按钮按下时,弹开集合中所有的按钮都会变为开状态。现在小K想知道是否能让所有的按钮变为闭合状态。如果能,打印最少步数以及方案,否则,打印“no solution”。
【输入格式】
第一行一个整数N,表示按钮的个数;
接下来N行,表示编号为1到N个按钮的弹开集合,格式为Mi,B1B2B3...BMi,表示编号为i的按钮按下时,会让编号为B1B2B3...BMi的按钮弹开(注:其中不会出现重复)
【输出格式】
如果无解,输出“no solution”;否则,第一行输出最少步数ret,第二行输出ret个数,表示按顺序按下编号为这些数的按钮就可以解决,每2个整数之间用一个空格隔开;如果有多种方案,请输出字典序最小的方案。
【样例输入】
6
2 2 3
0
2 4 5
0
0
0
【样例输出】
6
1 2 3 4 5 6
【数据规模】
对于40%的数据: 1≤N≤10;
对于100%的数据:1≤N≤30,000;令M=M1+M2+M3+...+MN,则0≤M≤1,000,000;
首先,要看出来这是个鬼畜的图论题。咋么看出来的?比方说,按钮1,不受任何按钮的牵制,更何况他的序号更小,那么肯定先按他,以后就不会再次按到他了。那么我们说第一问的答案如果有解肯定是n。为什么?举个例子,所有按钮都没牵制任何按钮,那么最少最少,也需要按n次。因为你需要的是按下每一个按钮,而每个按钮原来都是开着的,而且只能是自己按下按钮,而不是按下其他按钮导致的,所以得出ans1>=n。那么如果ans1>n,就说明n次以后肯定剩下了几个按钮,比如1,5,6。那么如果再按下1,5,6,必定又