奇怪的梦境
【题目描述】
Aiden陷入了一个奇怪的梦境:他被困在一个小房子中,墙上有很多按钮,还有一个屏幕,上面显示了一些信息。屏幕上说,要将所有按钮都按下才能出去,而又给出了一些信息,说明了某个按钮只能在另一个按钮按下之后才能按下,而没有被提及的按钮则可以在任何时候按下。可是Aiden发现屏幕上所给信息似乎有矛盾,请你来帮忙判断。
【输入描述】
第一行,两个数N,M,表示有编号为1...N这N个按钮,屏幕上有M条信息。
接下来的M行,每行两个数ai,bi,表示bi按钮要在ai之后按下。所给信息可能有重复,保证ai≠bi。
【输出描述】
若按钮能全部按下,则输出“^_^”。
若不能,第一行输出“T_T”,第二行输出因信息有矛盾而无法确认按下顺序的按钮的个数,输出不包括引号。
【样例输入】
3 3
1 2
2 3
3 2
【样例输出】
T_T
2
【数据范围及提示】
对于30%的数据,保证0<N≤100。
对于50%的数据,保证0<N≤2000。
对于70%的数据,保证0<N≤5000。
对于100%的数据,保证0<N≤10000,0<M≤2.5N。
源代码: #include<cstdio> #define INF 1000000000 int m,n,num(0),h[10001]={0}; bool f[10001][10001]={0}; int main() //拓扑排序。 { scanf("%d%d",&n,&m); for (int a=1;a<=m;a++) { int t1,t2; scanf("%d%d",&t1,&t2); f[t1][t2]=true; //是否连通。 h[t2]++; //入度。 } for (int a=1;a<=n;a++) { int t=1; while (h[t]&&t<n) t++; num++; //可行的点数。 bool k(0); for (int b=1;b<=n;b++) { if (f[t][b]) h[b]--; if (!h[b]&&b!=t) //是否还具有可行点。 k=true; } if (!k) { printf("T_T\n%d",n-num); break; } h[t]=INF; //赋给入度为极大值,从而不会再选择它。 if (a==n) printf("^_^"); } return 0; }