zoukankan      html  css  js  c++  java
  • HDU1181 Rank of Tetris(重写)拓扑排序+并查集

    这题一个地方没注意,导致错了很多次,之后还一直没找到错误。

    出问题的地方就是在第一轮找入度为零的节点的时候直接找的祖先节点,导致祖先节点多次入队~~~

    代码如下:

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    using namespace std;
    
    int N, M, set[10005], pos, cc;
    int rec[10005][2];
    char r[10005][5];
    
    struct Edge
    {
        int no, next;
    }e[20005];
    
    struct Node
    {
        int de, next;    
    }p[10005];
    
    int find(int x)
    {
        return set[x] = x == set[x] ? x : find(set[x]);
    }
    
    void merge(int a, int b)
    {
        set[a] = b;
    }
    
    void insert(int x, int y)
    {
        ++pos;
        e[pos].next = p[x].next;
        p[x].next = pos;  // 先建立逻辑关系,再更新数据
        e[pos].no = y;
        ++p[y].de;
    }
    
    void topology()
    {
        int uc = false, pos, count = 0;
        queue<int>q;
        for (int i = 0; i < N; ++i) {
        //    cur = find(i); 这样写可能使得祖先节点多次入队!!!!
            if (p[i].de == 0 && set[i] == i) {
                q.push(i);
            }
        }
        if (q.size() > 1) { // 直接判定队列的大小是否为1既可,非常方便
            uc = true;
        }
        while (!q.empty()) {
            ++count;  // 统计取出的点的总个数
            pos = q.front();
            q.pop();
            for (int i = p[pos].next; i != -1; i = e[i].next) { 
                if(--p[e[i].no].de == 0) {  // 每次在做过修改的点上考虑是否入队,这样能够避免单纯找度为零所带来的去重操作
                    q.push(e[i].no);
                }
            }
            if (q.size() > 1) {
                uc = true;
            }
        }
        if (count < N-cc) {
            puts("CONFLICT");
        }
        else if (uc){
            puts("UNCERTAIN");
        }
        else {
            puts("OK");
        }
    }
    
    int main()
    {
        int x, y;
        while (scanf("%d %d", &N, &M) != EOF) {
            pos = cc = 0;
            for (int i = 0; i < N; ++i) {
                p[i].de = 0;
                p[i].next = -1;
                set[i] = i;
            }
            for (int i = 1; i <= M; ++i) {
                scanf("%d %s %d", &rec[i][0], r[i], &rec[i][1]);
                if (r[i][0] == '=') {
                    int a = find(rec[i][0]), b = find(rec[i][1]);
                    if (a != b) {
                        ++cc;
                        merge(a, b);
                    }
                }
            }
            for (int i = 1;  i <= M; ++i) {
                 x = find(rec[i][0]), y = find(rec[i][1]);
                 switch (r[i][0]) {
                    case '<': {
                        insert(x, y);
                        break;
                    }
                    case '>': {
                        insert(y, x);
                        break;
                    }
                }
            }
            topology();
        }    
        return 0;
    }
  • 相关阅读:
    带参的方法
    类的无参方法
    类和对象
    关于线程间的通信的几个解决事例
    一个简单的邮件发送
    关于process
    关于java的static语句块
    关于struts2拦截器获取页面参数
    hexo github pages 首页不展示,出现代码怎么办
    使用Hexo搭建个人博客(三)
  • 原文地址:https://www.cnblogs.com/Lyush/p/2572820.html
Copyright © 2011-2022 走看看