您的位置:首页 > 其它

HDOJ 5154 Harry and Magical Computer (拓扑排序)

2017-07-23 10:19 337 查看


Harry and Magical Computer

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)


Problem Description

In reward of being yearly outstanding magic student, Harry gets a magical computer. When the computer begins to deal with a process, it will work until the ending of the processes. One day the computer got n processes to deal with. We number the processes from
1 to n. However there are some dependencies between some processes. When there exists a dependencies (a, b), it means process b must be finished before process a. By knowing all the m dependencies, Harry wants to know if the computer can finish all the n processes.

 

Input

There are several test cases, you should process to the end of file.

For each test case, there are two numbers n m on the first line, indicates the number processes and the number of dependencies. 1≤n≤100,1≤m≤10000

The next following m lines, each line contains two numbers a b, indicates a dependencies (a, b). 1≤a,b≤n

 

Output

Output one line for each test case. 

If the computer can finish all the process print "YES" (Without quotes).

Else print "NO" (Without quotes).

 

Sample Input

3 2
3 1
2 1
3 3
3 2
2 1
1 3

 

Sample Output

YES
NO

 

    题目大意:有向图的判环问题。

    知识点:

                 入度: 该点被其它点所指的条数。如:1->2、3->2,其中1、3的入度为0, 2的入度为2. 

                 判环核心思想:  通过(点的总数个)次循环,

                                               每次从入度为0的点开始,自己的入度减1(就是-1了),

                                               并且把该点所有指向的点的入度减一,且与这些点不再互通;

                                               如果循环还没有结束,却发现剩余点没有一个的入度为0,说明必定有环。

    请读者自行建图并模拟证明过程。

    AC代码如下:

    

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
using namespace std;
//HDOJ 5154

const int L = 105;
int n,m;
int maz[L][L];      //记录谁到谁是通的
int in[L];  //入度
bool topu()
{
int i,j;
for(i=1;i<=n;i++){ //总共点的个数 次循环
int u = -1;
for(j=1;j<=n;j++){
if(in[j]==0){   //找“ 一个 ” 入度为0的点
in[j]--;    //该点入度减一
u = j;      //记录该点下标
break;
}
}
if(u == -1)     //没有入度为0的点,必有环
return false;
for(j=1;j<=n;j++){
if(maz[u][j]){  //对该点“ 所有 ”指向的点的入度减一
in[j]-- ;
maz[u][j] = 0;  //不再互通
}
}
}
return true;
}

int main()
{
int i,j;
int a,b;
while(scanf("%d%d",&n,&m)!=EOF){
memset(maz,0,sizeof(maz));
memset(in,0,sizeof(in));
for(i=0;i<m;i++){
scanf("%d%d",&a,&b);
if(!maz[a][b]){     //去重
maz[a][b] = 1;
in[b] ++ ;  //被指点入度加一
}
}
if(topu())
printf("YES\n");
else
printf("NO\n");
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: