hdu3342-判断有向图中是否存在3元环-拓扑排序
题目大意:
给你一个关系图,判断是否合法,
每个人都有师父和徒弟,可以有很多个;
但是你的师父不能是你徒弟的徒弟,或者说你的徒弟不能是你师父的师父,这是不合法的情况。
简单理解就是:判断有向图中是否存在3元环;
此题至少有三种做法,此处跟新拓扑排序的做法:
1. 拓扑排序:
1. 统计每个点的入度;
2. 将入度为0的点加入队列;
3. 出去队首元素,将此元素所连接的点入度减一,若此后入度为0则加入队列;
4. 判断队列循环次数,若等于n则不存在3元环,则此关系图合法;
题目链接:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<queue> #include<map> #include<stack> #include<vector> #include<ctime> using namespace std; const int N = 2005; const int M = 3000005; int n,m; int tot,flag; int in[N],head[N]; struct lp { int u,v,nex; lp(){} lp(int a,int b,int c): u(a),v(b),nex(c){} }cw[N]; void add(int a,int b){ cw[++tot]=lp(a,b,head[a]); head[a]=tot; } void tuopu(){ queue<int>Q; while(!Q.empty())Q.pop(); for(int i=0;i<n;++i){ if(in[i]==0)Q.push(i); } int t=0; while(!Q.empty()){ t++; int u=Q.front();Q.pop(); for(int i=head[u];i!=-1;i=cw[i].nex){ int v=cw[i].v; in[v]--; if(in[v]==0)Q.push(v); } } if(t==n)flag=1; } int main(int argc, char const *argv[]) { int a,b; while(~scanf("%d%d",&n,&m)&&(n)){ memset(in,0,sizeof(in)); tot=-1; memset(head,-1,sizeof(head)); for(int i=0;i<m;++i){ scanf("%d%d",&a,&b); add(a,b); in[b]++; } flag=0; tuopu(); if(flag)printf("YES\n"); else printf("NO\n"); } return 0; }
View Code