HDU 3342 Legal or Not (图是否有环)【拓扑排序】

<题目链接>

题目大意:

给你 0~n-1 这n个点,然后给出m个关系 ,u,v代表u->v的单向边,问你这m个关系中是否产生冲突。

解题分析:

不难发现,题目就是叫我们判断图中是否存在环,存在环,则说明冲突。所以我们对图进行拓扑排序,如果该图中所有的点均能在拓扑排序中成为入度为0的点,则说明不含环(因为环中的点不可能入度为0)。

 1 #include <cstdio>
 2 #include <cstring>
 3 
 4 #define rep(i,s,t) for(int i=s;i<t;i++)
 5 const int N = 110;
 6 int g[N][N],ans[N][N],ind[N];
 7 int n,m,num,cur,last;
 8 bool toposort(){
 9     cur=last=-1,num=0;    
10     rep(k,0,n){
11         rep(i,0,n) if(!ind[i]){
12             cur=i;break;
13         }
14         if(cur==last)return false;  //用last记录上一次入度为0的点,即如果cur经过一次循环查找后仍然等于last,说明图中已经不存在入度为0的点
15         ++num;ind[cur]=-1;
16         if(num==n)return true;   //如果n个点均能依次在拓扑排序中成为入度为0的点,说明不存在环,即该图不产生冲突
17         rep(i,0,n) if(g[cur][i]){
18             ind[i]--;   //入度-1
19         }
20         last=cur;   //更新last
21     }
22     return false;
23 }
24 int main(){
25     while(~scanf("%d%d",&n,&m),n||m){
26         memset(g,0,sizeof(g));
27         memset(ind,0,sizeof(ind));
28         rep(i,0,m){
29             int u,v;scanf("%d%d",&u,&v);
30             if(!g[u][v]){    //防止重边
31                 g[u][v]=1;
32                 ind[v]++;
33             }
34         }
35         toposort()?puts("YES"):puts("NO");
36     }
37 }

 

 

2018-11-20

posted @ 2018-11-20 19:43  悠悠呦~  阅读(183)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end