• 并查集+拓扑 hdu 1811 Rank of Tetris


    hdu 1811 Rank of Tetris
    //hdu 1811 Rank of Tetris
    //并查集+拓扑
    
    //思路:用并查集把相等的点归到一起,再用拓扑
    
    //纠结这题纠结了一整天,看了n多的博客感觉这个不错
    //http://972169909-qq-com.iteye.com/blog/1052820
    
    
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    
    using namespace std;
    
    #define comein freopen("in.txt", "r", stdin);
    #define N 10005
    #define M 20005
    #define INF 1<<30
    #define eps 1e-5
    
    struct edge
    {
        int win, lost, next;
    }adja[M];
    
    int  tot;   //记录插入邻接表的个数
    int degree[N];
    int win[M], lost[M], head[N], set[N];
    
    int find(int root)
    {
        if(root == set[root])
            return root;
        return set[root] = find(set[root]);
    }
    
    void add_edge(int r_a, int r_b)
    {
        degree[r_b]++;
        adja[++tot].win = r_a;
        adja[tot].lost = r_b;
        adja[tot].next = head[r_a];
        head[r_a] = tot;
    }
    
    void topo(int n_node, int all)
    {
        queue<int>que;
        bool uncer = false;
        for(int i = 0; i < n_node; ++i)//要集合根节点且度为0的才可入队,若只判断
            if(degree[i] == 0 && i == find(i))  //degree[find(i)]==0,可能会重复入队
                que.push(i);
        while(!que.empty())
        {
            if(que.size() > 1)
                uncer = true;
            int now = que.front();
            que.pop();
            all--;
            for(int i = head[now]; i != -1; i = adja[i].next)
            {
                if(--degree[ adja[i].lost ] == 0)
                    que.push( adja[i].lost );
            }
        }
        if(all > 0) //剩下的集合数大于1,则存在环
            puts("CONFLICT");
        else if(uncer == true)
            puts("UNCERTAIN");
        else
            puts("OK");
    }
    
    int main()
    {
        // comein
        int n_node, n_pair;
        while(scanf("%d%d", &n_node, &n_pair) == 2)
        {
            for(int i = 0; i <= n_node; ++i)    //初始化并查集
                set[i] = i;
    
            int cnt = 0, all = n_node;    //若相等的点看做一个点,cnt记录总的点数
    
            for(int i = 0; i < n_pair; ++i)
            {
                int wn, lt;
                char ra;
                scanf("%d %c %d", &wn, &ra, &lt);
                if(ra == '=')
                {   //这里要先求出来r_a和r_b,然后下面要用set[r_a] = r_b
                    //或set[r_b] = r_a,也不知道为什么,一天下来都在找bug
                    //无缘无故就被de掉了,提交了30几次,有的这里不用这样也可以ac
                    //有的不能,快崩溃了
                    int r_a = find(wn), r_b = find(lt);
                    if(r_a != r_b)
                    {
                        set[r_a] = r_b;
                        all--;
                    }
                }
                else if(ra == '>')
                {
                    win[++cnt] = wn;
                    lost[cnt] = lt;
                }
                else
                {
                    win[++cnt] = lt;
                    lost[cnt] = wn;
                }
            }
    
            memset(adja, 0, (n_pair+5)*sizeof(edge));
            for(int i = 0; i < n_node; ++i)
            {
                head[i] = -1;
                degree[i] = 0;
            }
            tot = 0;
            bool flag = false;
            for(int i = 1; i <= cnt; ++i)
            {
                int r_a = find(win[i]), r_b = find(lost[i]);
                if(r_a == r_b)  //上面的已经把'='的情况合并起来了
                {           //这里都是处理不等的,如果出现相等的,说明冲突了
                    flag = true;
                    break;
                }
                add_edge(r_a, r_b);
            }
            if(flag == true)
            {
                puts("CONFLICT");
                continue;
            }
            topo(n_node, all);
        }
        return 0;
    }
  • 相关阅读:
    PAT (Advanced Level) 1080. Graduate Admission (30)
    PAT (Advanced Level) 1079. Total Sales of Supply Chain (25)
    PAT (Advanced Level) 1078. Hashing (25)
    PAT (Advanced Level) 1077. Kuchiguse (20)
    PAT (Advanced Level) 1076. Forwards on Weibo (30)
    PAT (Advanced Level) 1075. PAT Judge (25)
    PAT (Advanced Level) 1074. Reversing Linked List (25)
    PAT (Advanced Level) 1073. Scientific Notation (20)
    PAT (Advanced Level) 1072. Gas Station (30)
    PAT (Advanced Level) 1071. Speech Patterns (25)
  • 原文地址:https://www.cnblogs.com/gabo/p/2609228.html
Copyright © 2020-2023  润新知