您的位置:首页 > 其它

hdu Harry and Magical Computer 拓扑排序(简单)

2015-05-21 16:19 573 查看
Harry and Magical Computer Accepts: 475 Submissions: 1954 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*

Statistic | Submit | Clarifications | Back

**这是典型的一个拓扑排序的题。计算机可以执行n条程序,但是有m条限制,比如(a,b)有依赖关系,则b必须比a先执行,就像一个有向图,如果产生了冲突说明有回路

最主要的是判断是否有回路,也可以用深搜**

拓扑排序

首先标记一下(a,b)之间有通路,由于是有序的,因此标记时要注意顺序,比如a->b,则记为f[a][b]=1,记录入度rd[b]+1,全部标记好之后,先找到入度为0的点(比如a),对于无环有向图必定存在入度为0的点,否则结束,然后要把a标记为-1,避免重复找a,然后与a相连的点比如a->b,a->c,则b,c的入度都要减1,再重复找入度为0的点,如果最后还有点入度大于0,则说明有冲突,如果有的点入度为0,则说明不是一个连通图

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[105][105];
int rd[105];
bool flag;
void tuopu(int n)
{
for(int i = 1; i<=n; i++){
int j;
for( j = 1;j<=n;j++)
if(!rd[j])break;
if(j>n){
flag=1;
break;
}
else{
rd[j]--;
for(int k=1;k<=n; k++)
if(f[j][k]!=-1){
if(rd[k])
rd[k]--;
}
}

}
for(int i = 1; i<=n; i++){
if(rd[i]>0){
flag=1;
break;
}
}
}
int main()
{
int m,n;
while(scanf("%d%d",&n,&m)!=-1)
{
flag=0;
int a,b;
memset(f,-1,sizeof(f));
memset(rd,0,sizeof(rd));
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
if(f[a][b]==-1){//避免可能会有重复的
f[a][b]=1;
rd[b]++;
}
}
tuopu(n);
if(flag)
puts("NO");
else puts("YES");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: