首页 > 其他 > 详细

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

时间:2014-08-13 17:39:27      阅读:363      评论:0      收藏:0      [点我收藏+]

做了这题 绝逼 累啊..

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搞的

bubuko.com,布布扣
  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;//conflict
101                 }
102             }
103         }
104         topo();
105         if (flag)
106             cout << "CONFLICT" << endl;
107         else
108         {
109             if (ans)
110                 cout << "UNCERTAIN" << endl;
111             else
112                 cout << "OK" << endl;
113         }
114     }
115     return 0;
116 }
View Code

 

bubuko.com,布布扣
  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         else
107             cout << "OK" << endl;
108     }
109     return 0;
110 }
View Code

 

bubuko.com,布布扣
  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         else
100             cout << "OK" << endl;
101     }
102     return 0;
103 }
View Code

 

hdu--1811--并查集&&拓扑排序<好题>,布布扣,bubuko.com

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

原文:http://www.cnblogs.com/radical/p/3910103.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!