首页 > 代码库 > hdu--1811--并查集&&拓扑排序<好题>

hdu--1811--并查集&&拓扑排序<好题>

做了这题 绝逼 累啊..

mle -- re<stack overflow>--tle--wa---ac

经过这么5步 终于AC了

这题 我觉得可以让你更好地来 理解 拓扑排序的一些细节问题

首先 这题 为什么要用到并查集呢? 因为 会有 A = B这种情况的出现 然后可能再来个 B =C A = D....那么我们就需要将它们全部表示成一个点 那么就是都用一个根结点来表示

然后 这边 是要判断 能不能根据给出的条件 形成一个排列 那么就是个 拓扑问题 根据 > <情况来判断

我觉得 解这题的几点核心思想:

1.如果要对N个元素进行拓扑排序 那么如果每次 入度为0的点超过2个 就会形成多种排序结果 所以 这也就是 一般我们做拓扑的时候 题目会要求我们什么按照字典序来输出什么的 因为存在满足要求情况不止一种啊  但这边 很特殊 它一定严格按照><=来输出 所以我们可以对每次队列中的元素个数进行判断 如果大于一个 就可以确定这是不确定 即 q.size()>1

2.拓扑排序是基于---DAG<有向无环图>     其实也就是告诉我们 可以根据拓扑来判断 这个图中是否存在环? 我们只要每次有一个元素被取出 就进行统计 最后再判断下 一共被取出的元素数目  与 需要进行拓扑的元素数目 是否相等 如果不相等 就可以说它是 成环的

---我感觉 这2点 应该算是最重要的 但还有很多细节 地方要注意的   我一共写了好多份代码...

一开始 我走错了个方向 我忘记考虑了 成环的存在 我判断 A>B 是否与 A<B 同时存在 来判断conflict 这样虽然样例过了但是 我mle同时 也是错误的

恩 对了 这边进行初始入队的时候很重要一点是  这个结点 不仅仅要求是入度为0 而且是 根结点  因为不是根结点的 已经被我们合并掉了 没有纳入我们总的元素数量考虑

所以 这边 我后来做的时候 又犯了一次错误

我们对于输入的 A OP B 需要进行2次处理  第一次是把 = 号关系的2个结点合并 每次 合并 都需要对总的数目--

其实 这个合并不难理解 因为主要是来因对 A = B   B = D D>C 这种类似的情况的

        touch  me

这边 题目是没有要求我们输出最终结果 但是 如果要输出的话 我们也只要根据这句话就好了 ---如果两个人具有相同的Rating,那就按这几个人的RP从高到低来排----

好了 贴下代码 有点乱啊 被这vs搞的

  1 #include <iostream>  2 #include <cstring>  3 #include <map>  4 #include <queue>  5 using namespace std;  6   7 bool ans;  8 int n;  9 const int size = 10010; 10 int in[size]; 11 int father[size]; 12 char mp[size][size]; 13 map<char, int>op; 14 queue<int>q; 15  16 int find(int x) 17 { 18     while( father[x]!=-1 ) 19     { 20         father[x] = father[ father[x] ]; 21         x = father[x]; 22     } 23     return x; 24 } 25  26 void topo() 27 { 28     for (int i = n - 1; i >= 0; i--) 29     { 30         if (!in[i]) 31         { 32             q.push(i); 33         } 34     } 35     while (!q.empty()) 36     { 37         if (q.size()>1) 38             ans = true;// uncertain 39         int now = q.front(); 40         q.pop(); 41         for ( int i = 0 ; i<n ; i++ ) 42         { 43             if( mp[now][i]==2 ) 44             { 45                 in[i] --; 46                 if( in[i]==0 ) 47                 { 48                     q.push(i); 49                 } 50             } 51         } 52     } 53 } 54  55 int main() 56 { 57     cin.sync_with_stdio(false); 58     int m , x , y; 59     char ch; 60     bool flag; 61     while (cin >> n >> m) 62     { 63         memset(father, -1, n*sizeof(int)); 64         memset(mp,0, sizeof(mp)); 65         memset(in, 0, n*sizeof(int)); 66         op[=] = 1; 67         op[>] = 2; 68         op[<] = 3; 69         ans = flag = false; 70         while (m--) 71         { 72             cin >> x >> ch >> y; 73             x = find(x); 74             y = find(y); 75             if (mp[x][y]==0) 76             { 77                 if (ch == =) 78                 { 79                     mp[x][y] = 1;//1是平局 80                     mp[y][x] = 1; 81                     father[y] = x; 82                 } 83                 else if (ch == >) 84                 { 85                     mp[x][y] = 2;//2是大于 86                     mp[y][x] = 3;//3是小于 87                     in[y] ++; 88                 } 89                 else 90                 { 91                     mp[x][y] = 3; 92                     mp[y][x] = 2; 93                     in[x] ++; 94                 } 95             } 96             else 97             { 98                 if (op[ch] != mp[x][y]) 99                 {100                     flag = true;//conflict101                 }102             }103         }104         topo();105         if (flag)106             cout << "CONFLICT" << endl;107         else108         {109             if (ans)110                 cout << "UNCERTAIN" << endl;111             else112                 cout << "OK" << endl;113         }114     }115     return 0;116 }
View Code

 

  1 #include <iostream>  2 #include <cstring>  3 #include <vector>  4 #include <queue>  5 using namespace std;  6   7 int n , cnt;  8 bool CONFLICT , UNCERTAIN;  9 const int size = 10010; 10 int x[size]; 11 int y[size]; 12 char ch[size]; 13 int in[size]; 14 int father[size]; 15 vector<int>ve[size]; 16 queue<int>q; 17  18 void init( ) 19 { 20     memset( father , -1 , sizeof(father) ); 21     memset( in , 0 , sizeof(in) ); 22     for( int i = 0 ; i<size ; i++ ) 23     { 24         ve[i].clear(); 25     } 26 } 27  28 int find( int x ) 29 { 30     return father[x] == -1 ? x : father[x] = find( father[x] ); 31 } 32  33 void topo( ) 34 { 35     for( int i = 0 ; i<n ; i++ ) 36     { 37         if( !in[i] && father[i] == -1 ) 38         { 39             q.push(i); 40         } 41     } 42     while( !q.empty() ) 43     { 44         if( q.size()>1 ) 45             UNCERTAIN = true; 46         int now = q.front(); 47         q.pop(); 48         cnt --; 49         for( int i = 0 ; i<ve[now].size() ; i++ ) 50         { 51             int u = ve[now][i]; 52             if( --in[u] == 0 ) 53             { 54                 q.push(u); 55             } 56         } 57     } 58     if( cnt>0 ) 59         CONFLICT = true; 60 } 61  62 int main() 63 { 64     int m , xx , yy; 65     while( cin >> n >> m ) 66     { 67         init( ); 68         cnt = n; 69         CONFLICT = UNCERTAIN = false; 70         for( int i = 0 ; i<m ; i++ ) 71         { 72             cin >> x[i] >> ch[i] >> y[i]; 73             if( ch[i]=== ) 74             {     75                 xx = find(x[i]); 76                 yy = find(y[i]); 77                 if(xx!=yy) 78                 { 79                     father[xx] = yy; 80                     cnt --; 81                 } 82             } 83         } 84         for( int i = 0 ; i<m ; i++ ) 85         { 86             if( ch[i] == = ) 87                 continue; 88             xx = find(x[i]); 89             yy = find(y[i]); 90             if( ch[i]==> ) 91             { 92                 ve[xx].push_back(yy); 93                 in[yy] ++; 94             } 95             else 96             { 97                 ve[yy].push_back(xx); 98                 in[xx] ++; 99             }100         }101         topo( );102         if( CONFLICT )103             cout << "CONFLICT" << endl;104         else if( UNCERTAIN )105             cout << "UNCERTAIN" << endl;106         else107             cout << "OK" << endl;108     }109     return 0;110 }
View Code

 

  1 //1. 当入队的个数 >1 时证明拓扑排序结果不唯一 uncertain  2 //2. 入队进行拓扑排序的元素 < 总共的元素个数 成环的存在 conflict   3 #include <iostream>  4 #include <cstring>  5 #include <vector>  6 #include <queue>  7 using namespace std;  8   9 int n , cnt; 10 bool CONFLICT , UNCERTAIN; 11 const int size = 10010; 12 int in[size]; 13 int father[size]; 14 vector<int>ve[size]; 15 queue<int>q; 16  17 void init( ) 18 { 19     memset( father , -1 , sizeof(father) ); 20     memset( in , 0 , sizeof(in) ); 21     for( int i = 0 ; i<size ; i++ ) 22     { 23         ve[i].clear(); 24     } 25 } 26  27 int find( int x ) 28 { 29     return father[x] == -1 ? x : father[x] = find( father[x] ); 30 } 31  32 void topo( ) 33 { 34     for( int i = 0 ; i<n ; i++ ) 35     { 36         if( !in[i] && father[i] == -1 ) 37         { 38             q.push(i); 39         } 40     } 41     while( !q.empty() ) 42     { 43         if( q.size()>1 ) 44             UNCERTAIN = true; 45         int now = q.front(); 46         q.pop(); 47         cnt --; 48         for( int i = 0 ; i<ve[now].size() ; i++ ) 49         { 50             int u = ve[now][i]; 51             if( --in[u] == 0 ) 52             { 53                 q.push(u); 54             } 55         } 56     } 57     if( cnt>0 ) 58         CONFLICT = true; 59 } 60  61 int main() 62 { 63     int m , x , y; 64     char ch; 65     while( cin >> n >> m ) 66     { 67         init( ); 68         cnt = n;//原来的元素总数 69         CONFLICT = UNCERTAIN = false;//1是关于conflice  2是关于uncertain 70         while( m-- ) 71         { 72             cin >> x >> ch >> y; 73             x = find(x); 74             y = find(y); 75             if( ch=== ) 76             { 77                 if(x!=y) 78                 { 79                     father[x] = y; 80                     cnt --; 81                 } 82             } 83             else if( ch==> ) 84             { 85                 ve[x].push_back(y); 86                 in[y] ++; 87             } 88             else 89             { 90                 ve[y].push_back(x); 91                 in[x] ++; 92             } 93         } 94         topo( ); 95         if( CONFLICT ) 96             cout << "CONFLICT" << endl; 97         else if( UNCERTAIN ) 98             cout << "UNCERTAIN" << endl; 99         else100             cout << "OK" << endl;101     }102     return 0;103 }
View Code