<题目链接>
题目大意:
给你 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