hdu 3342 Legal or Not 拓扑排序学习整理

来源:互联网 发布:淘宝pv和uv是什么意思 编辑:程序博客网 时间:2024/05/15 06:30

ACM-DIY is a large QQ group where many excellent acmers get together. It is so harmonious that just like a big family. Every day,many "holy cows" like HH, hh, AC, ZT, lcc, BF, Qinz and so on chat on-line to exchange their ideas. When someone has questions, many warm-hearted cows like Lost will come to help. Then the one being helped will call Lost "master", and Lost will have a nice "prentice". By and by, there are many pairs of "master and prentice". But then problem occurs: there are too many masters and too many prentices, how can we know whether it is legal or not?

We all know a master can have many prentices and a prentice may have a lot of masters too, it's legal. Nevertheless,some cows are not so honest, they hold illegal relationship. Take HH and 3xian for instant, HH is 3xian's master and, at the same time, 3xian is HH's master,which is quite illegal! To avoid this,please help us to judge whether their relationship is legal or not. 

Please note that the "master and prentice" relation is transitive. It means that if A is B's master ans B is C's master, then A is C's master.
Input
The input consists of several test cases. For each case, the first line contains two integers, N (members to be tested) and M (relationships to be tested)(2 <= N, M <= 100). Then M lines follow, each contains a pair of (x, y) which means x is y's master and y is x's prentice. The input is terminated by N = 0. 
TO MAKE IT SIMPLE, we give every one a number (0, 1, 2,..., N-1). We use their numbers instead of their names.
Output
For each test case, print in one line the judgement of the messy relationship. 
If it is legal, output "YES", otherwise "NO".
Sample Input
3 20 11 22 20 11 00 0
Sample Output
YESNO


题目大意:输入n、m,n代表有n个点从0......n-1,m代表有m条路径,判断该有向图是否有环,有环输出no,否则输出yes。

算是用这个题学习了一下拓扑排序吧...

拓扑排序的用处之一就是判断一个有向图中是否有环。

定义:将有向图中的顶点以线性方式进行排序。即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面。(emmmm........)。

实现原理:先将所有度为0的点入队列,

举个例子吧

原理是将入度为零的点先入队列(我是用队列实现的),在从图中把这些点去掉,输出队首元素,出队列,再将入度为零的点入队列,直到队列为空。

while(队列不空){

①入度为零的点入队列,并将这些点在图中删除。

②队首元素输出,出队列。

}

如果最后所有的点都如果队列,那么图没有环。否则有环。

上面的排序后: 2->8->0->3->7->1->5->6->9->4->11->10->12

过程就是这么简单!!!!!

#include<iostream>#include<cstring>#include<cstdio>#include<queue>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;//输入n、m,n个点0......n-1,m条路径,判断是否有环,有环输出no。 int map[105][105],dis[105];int main(){int n,m,x,y,count;while(scanf("%d%d",&n,&m)&&n){memset(map,0,sizeof(map));memset(dis,0,sizeof(dis)); count=0;for(int i=0;i<m;i++){scanf("%d%d",&x,&y);if(map[x][y]==0){                map[x][y]=1;                dis[y]++;            }}queue<int> q;for(int i=0;i<n;i++)if(dis[i]==0){q.push(i);count++;}while(!q.empty()){int temp=q.front();q.pop();for(int i=0;i<n;i++){if(map[temp][i]){dis[i]--;if(!dis[i]){q.push(i);count++;}}}}if(count==n)printf("YES\n");elseprintf("NO\n");}    return 0;}



 



原创粉丝点击