您的位置:首页 > 其它

CODEVS P2833 奇怪的梦境 解题报告

2018-04-03 17:16 225 查看

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。

随便找了一道纯拓扑排序的题练了一下,感觉就是个模板题,非常水,毕竟难度等级只有这么低。
看懂题目的意思发现其实就是ai到bi建一条有向边,建完边之后跑一边拓扑排序,最后判断是否所有点都能删了。
如果有环,就表明不能打成目标,直接输出总点数-已删点数就行了。
至于拓扑排序的方法到处都有,我就不作解释了。#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAXN=100001;
struct edge
{
int node,next,w;
}h[MAXN];//这个数据要用邻接表来存
int Head[MAXN],Dg[MAXN],stack[MAXN];//这里我用的栈,感觉比较顺手,其实都无所谓就是顺序不一样。
int n,m,tot,top=0,sum=0;
void add(int u,int v)//邻接表加边
{
h[++tot].next=Head[u];
h[tot].node=v;
Head[u]=tot;
}
void push(int x)
{
stack[++top]=x;
}
int pop()
{
return stack[top--];
}//栈的两个操作
void TPsort()//拓扑排序
{
for(int i=1;i<=n;i++)
if(!Dg[i])
push(i);
int v;
while(top)
{
int x=pop();
sum++;
for(int i=Head[x];i;i=h[i].next)
{
v=h[i].node;
if(Dg[v])
Dg[v]--;
if(!Dg[v])
push(v);
}
}
if(sum==n)
cout<<"o(∩_∩)o";
else
cout<<"T_T"<<endl<<n-sum;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
Dg[y]++;
}
TPsort();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  拓扑排序