2833 奇怪的梦境
2833 奇怪的梦境
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
Aiden陷入了一个奇怪的梦境:他被困在一个小房子中,墙上有很多按钮,还有一个屏幕,上面显示了一些信息。屏幕上说,要将所有按钮都按下才能出去,而又给出了一些信息,说明了某个按钮只能在另一个按钮按下之后才能按下,而没有被提及的按钮则可以在任何时候按下。可是Aiden发现屏幕上所给信息似乎有矛盾,请你来帮忙判断。
输入描述 Input Description
第一行,两个数N,M,表示有编号为1...N这N个按钮,屏幕上有M条信息。
接下来的M行,每行两个数ai,bi,表示bi按钮要在ai之后按下。所给信息可能有重复,保证ai≠bi。
输出描述 Output Description
若按钮能全部按下,则输出“o(∩_∩)o”。
若不能,第一行输出“T_T”,第二行输出因信息有矛盾而无法确认按下顺序的按钮的个数。输出不包括引号。
样例输入 Sample Input
3 3
1 2
2 3
3 2
样例输出 Sample Output
T_T
2
数据范围及提示 Data Size & Hint
对于30%的数据,保证0<N≤100。
对于50%的数据,保证0<N≤2000。
对于70%的数据,保证0<N≤5000。
对于100%的数据,保证0<N≤10000,0<M≤2.5N。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 int top=0; 6 struct sta{ 7 int sz[90001]; 8 int topp() 9 { 10 return sz[top]; 11 } 12 void push(int x){ 13 sz[++top]=x; 14 } 15 void pop(){ 16 if(top>0) 17 top--; 18 } 19 void cl() 20 { 21 top=0; 22 } 23 int size(){ 24 return top; 25 } 26 }stack; 27 struct node{ 28 int u,v,next; 29 }edge[100001]; 30 int num=1;int head[10001]; 31 void add_edge(int x,int y) 32 { 33 edge[num].u=x; 34 edge[num].v=y; 35 edge[num].next=head[x]; 36 head[x]=num++; 37 } 38 39 int rude[100001],vis[100001]; 40 int main() 41 { 42 int n,m,x,y; 43 scanf("%d%d",&n,&m); 44 for(int i=1;i<=n;i++) 45 { 46 head[i]=-1; 47 } 48 for(int i=1;i<=m;i++) 49 { 50 scanf("%d%d",&x,&y); 51 add_edge(x,y); 52 rude[y]++; 53 } 54 int tot=0; 55 for(int i=1;i<=n;i++) 56 { 57 if(rude[i]==0) 58 { 59 tot++; 60 stack.push(i); 61 } 62 } 63 int step; 64 int ans=0; 65 while(stack.size()!=0) 66 { 67 step=stack.topp(); 68 stack.pop(); 69 for(int i=head[step];i!=-1;i=edge[i].next) 70 { 71 rude[edge[i].v]--; 72 if(rude[edge[i].v]==0) 73 { 74 stack.push(edge[i].v); 75 tot++; 76 } 77 } 78 } 79 if(tot==n-1)printf("o(∩_∩)o"); 80 else printf("T_T\n%d",n-tot); 81 return 0; 82 }