首页 > 代码库 > ACM1811拓扑排序和并查集
ACM1811拓扑排序和并查集
1 /* 2 ACM1811 可以利用拓扑排序和并查集解决,主要方式是利用并查集在输入数据的时候将所有相等的点合并 3 然后将处理完的数据统一按照一个符号方向连接成有向线段,利用的是邻接矩阵;接下来把每条边都进行履历 4 如果出现conflict,那么就会在去除所有入度的时候无法找到新的零入度点,那么就会似的point无法减到零, 5 表示有conflict,如果出现uncertain,那么就会在一次寻找新的零入度点时能找到多个点,导致在队列中保存 6 多个数据 ; 7 */ 8 #include<iostream> 9 #include<queue> 10 using namespace std; 11 class EDGE 12 { 13 public: 14 int from,to; 15 char sign; 16 }; 17 class WAY 18 { 19 public: 20 int from,to,next; 21 }; 22 class DEAL 23 { 24 public: 25 DEAL(int n,int m) 26 { 27 edge=new EDGE[m]; 28 way=new WAY[m]; 29 father=new int[n]; 30 head=new int[n]; 31 into=new int[n]; 32 for(int i=0;i<n;i++) 33 { 34 father[i]=i;head[i]=-1; 35 into[i]=0; 36 } 37 number=n; 38 point=n; 39 side=m; 40 count=0; 41 certain=true; 42 conflict=false; 43 } 44 ~DEAL() 45 { 46 delete []edge; 47 delete []father; 48 delete []way; 49 delete []head; 50 delete []into; 51 } 52 void Input() 53 { 54 for(int i=0;i<side;i++) 55 { 56 cin>>edge[i].from>>edge[i].sign>>edge[i].to; 57 if(edge[i].sign==‘=‘) 58 { 59 int fa=FindFather(edge[i].from); 60 int fb=FindFather(edge[i].to); 61 Union(fa,fb); 62 point--; 63 } 64 } 65 } 66 void Preprocess() 67 { 68 for(int i=0;i<side;i++) 69 { 70 if(edge[i].sign==‘=‘)continue; 71 int fa=FindFather(edge[i].from); 72 int fb=FindFather(edge[i].to); 73 if(fa==fb)conflict=true; 74 if(edge[i].sign==‘<‘) 75 Merge(fb,fa); 76 else if(edge[i].sign==‘>‘) 77 Merge(fa,fb); 78 } 79 } 80 void Toposort() 81 { 82 for(int i=0;i<number;i++) 83 { 84 if(into[i]==0&&father[i]==i)//是头节点 85 q.push(i); 86 } 87 while(!q.empty()) 88 { 89 int l=q.front(); 90 q.pop(); 91 point--; 92 if(!q.empty())certain=false; 93 int v; 94 for(v=head[l];v!=-1;v=way[v].next) 95 { 96 int u=way[v].to; 97 into[u]--; 98 if(!into[u])q.push(u); 99 }100 }101 }102 void Output()103 {104 if(point>0||conflict)105 cout<<"CONFLICT"<<endl;106 else if(!certain)cout<<"UNCERTAIN"<<endl;107 else cout<<"OK"<<endl;108 }109 int FindFather(int x)110 {111 if(x==father[x])return x;112 return father[x]=FindFather(father[x]);113 }114 void Union(int x,int y)115 {116 if(x!=y)father[y]=x;//后面跟着前面 117 }118 void Merge(int x,int y)119 {120 way[count].from=x;121 way[count].to=y;122 way[count].next=head[x];123 into[y]++;124 head[x]=count++;125 }126 private:127 queue<int>q;128 int number,side,point,count;129 EDGE *edge;130 WAY *way;131 int *father,*head,*into;132 bool certain,conflict;133 };134 int n,m;135 int main()136 {137 while(cin>>n>>m)138 {139 DEAL ob(n,m);140 ob.Input();141 ob.Preprocess();142 ob.Toposort();143 ob.Output();144 }145 return 0;146 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。