拓扑排序

拓扑排序

# include <bits/stdc++.h>
using namespace std;

const int LEN_of_Node=1e4+100;
const int LEN_of_Edge=2e4+100;
int cnt;
int n,m;
int num;
struct Edge
{
   int to,next;
};
Edge edge[LEN_of_Edge];
int head[LEN_of_Node];//领接表存图
int father[LEN_of_Node];//并查集用
int in[LEN_of_Node];//记录入度
int a[LEN_of_Node];
char c[LEN_of_Node];
int b[LEN_of_Node];
void init()//初始化函数
{
   cnt=1;
   memset(in,0,sizeof(in));
   memset(head,0,sizeof(head));
   for(int i=1;i<=n;i++) father[i]=i;
}
int Find(int x)//并查集所用函数
{
   return x==father[x]?x:father[x]=Find(father[x]);
}
void join(int aa,int bb)//并查集合并函数
{
   int x=Find(aa);
   int y=Find(bb);
   if(x!=y){
       in[x]=-1;
       father[x]=y;
  }
}
void Add(int u,int v)//邻接表添加节点的函数
{
   edge[cnt].next=head[u];
   edge[cnt].to=v;
   head[u]=cnt++;
}
int Topo()//拓扑排序
{
   queue<int> que; //用队列记录
   for(int i=1;i<=n;i++){
       if(in[i]==0&&i==Find(i)) que.push(i);
  }
   int sign=0;
   while(!que.empty()){
       if(que.size()>1)//如果有两个节点表明无法确定这两个节点的顺序,应为他们肯定不是同rating的(并查集合并过了);
      {
           sign=1;
      }
       int q=que.front();
       que.pop();
       in[q]=-1; //删除节点
       for(int i=head[q];i;i=edge[i].next){
           int tmp=edge[i].to;
           in[tmp]--;
           if(in[tmp]==0){//如果入度为零,则加入队列
               que.push(tmp);
          }
      }
  }
   for(int i=1;i<=n;i++){
       if(in[i]!=-1) return 2; //判断是否有没有处理的节点,如果有,说明肯定有环
  }
   if(sign) return 3;
   return 0;
}
int main()
{
   while(cin>>n>>m){
       init();
       for(int i=1;i<=m;i++){
           scanf("%d %c %d",&a[i],&c[i],&b[i]);
           a[i]++;
           b[i]++;
           if(c[i]=='='){//如果相等就合并
               join(a[i],b[i]);
          }
      }
       for(int i=1;i<=m;i++){
           if(c[i]=='=') continue;
           int aa=Find(a[i]);
           int bb=Find(b[i]);
           if(c[i]=='>'){
               Add(aa,bb);
               in[bb]++;
          }else{
               Add(bb,aa);
               in[aa]++;
          }
      }
       int sign=Topo();
       if(sign==0) printf("OK\n");
       else if(sign==2) printf("CONFLICT\n");
       else if(sign==3) printf("UNCERTAIN\n");
  }
   return 0;
}



posted @ 2022-02-27 13:49  fengzlj  阅读(140)  评论(0)    收藏  举报