zoukankan      html  css  js  c++  java
  • UVA 1572 SelfAssembly(图论模型+拓扑排序)

    题意:判断利用给出的正方形是否能拼接出无限延伸的结构。

    分析:正方形上的字母看做点,正方形看做有向边。

    例如:

    若上下两个正方形能拼接,需要B+~C+是个有向边。

    对输入的处理是:把A+,A-分别映射成2n+1,2n,利用(2n)^1 = 2n+1 , (2n+1)^1 = 2n 的性质处理有向边。

    若存在有向环则unbounded,即不存在拓扑排序

    #pragma comment(linker, "/STACK:102400000, 102400000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define Min(a, b) ((a < b) ? a : b)
    #define Max(a, b) ((a < b) ? b : a)
    typedef long long ll;
    typedef unsigned long long llu;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
    const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const double eps = 1e-8;
    const int MAXN = 52 + 10;
    const int MAXT = 10000 + 10;
    using namespace std;
    char s[10];
    int pic[MAXN][MAXN];
    int vis[MAXN];
    priority_queue<int> q;
    int get_id(char a, char b){
        return b == '+' ? 2 * (a - 'A') + 1 : 2 * (a - 'A');
    }
    bool dfs(int x){
        vis[x] = -1;
        for(int i = 0; i < 52; ++i){
            if(pic[x][i]){
                if(vis[i] == -1) return false;
                else if(!vis[i] && !dfs(i)) return false;
            }
        }
        vis[x] = 1;
        return true;
    }
    bool toposort(){
        for(int i = 0; i < 52; ++i){
            if(!vis[i] && !dfs(i)){
                return false;
            }
        }
        return true;
    }
    int main(){
        int n;
        while(scanf("%d", &n) == 1){
            memset(pic, 0, sizeof pic);
            memset(vis, 0, sizeof vis);
            while(n--){
                scanf("%s", s);
                for(int i = 0; i < 4; ++i){//处理除了00之外的点之间的有向边的关系
                    for(int j = 0; j < 4; ++j){
                        if(i != j && s[i * 2] != '0' && s[j * 2] != '0'){
                            int from = get_id(s[i * 2], s[i * 2 + 1]) ^ 1;
                            int to = get_id(s[j * 2], s[j * 2 + 1]);
                            pic[from][to] = 1;
                        }
                    }
                }
            }
            bool ok = toposort();
            if(ok){
                printf("bounded\n");
            }
            else{
                printf("unbounded\n");
            }
        }
        return 0;
    }
  • 相关阅读:
    被隐藏的文件更改为可见
    Selenium WebDriver多层表单切换
    for循环
    Java课程设计二次大作业
    Java-DAO模式代码阅读及应用
    编辑器、编译器、文件、IDE等常见概念辨析
    树、二叉树和查找等知识点的总结
    二叉树的实现
    二叉树顺序结构和链式结构的相互转换
    使用k-近邻算法改进约会网站的配对效果
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/6279506.html
Copyright © 2011-2022 走看看