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;
    }
  • 相关阅读:
    使用树莓派打造远程WEB服务器
    oracle 12c新建pdb实例
    word标题变成黑色方块解决
    idea 报JDBC连接失败原因之一
    maven项目pom.xml需要的一些配置
    Mysql时区无法识别
    数据库报ORA-12514
    win10无法在桌面右键快捷打开个性化设置、显示设置,在任务栏右键无法快捷打开任务栏设置
    Tomcat部署项目时,发布的项目页面部分乱码,且页面渲染文件也是乱码。
    高性能、高稳定性的跨平台MQTT客户端
  • 原文地址:https://www.cnblogs.com/Lyush/p/2572820.html
Copyright © 2011-2022 走看看