• uvalive 6393(uva 1572) Self-Assembly 拓扑排序


    题意:

    给出一些正方形,这些正方形的每一条边都有一个标号。这些标号有两种形式:1.一个大写字母+一个加减号(如:A+, B-, A-......), 2.两个0(如:00);这些正方形能够任意翻转和旋转。当两个正方形通过旋转或翻转,使得他们的公共边为同样大写字母而且符号相反时,他们就能够彼此结合拼在一起。如今给出n中正方形。每种正方形有无限多种,问这些正方形是否能拼成一个无限大的结构。

    题解:

    easy想到。要使这些正方形形成无限大地结构。那么这些正方形通过拼接后一定能循环(即通过不断地拼接出现了和曾经同样地正方形),那么就能够通过推断将这些正方形地全部可能地拼接方式连有向边。然后推断是否有有向环,就可以通过拓扑排序来推断。

    代码:

    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <sstream>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 52 + 10;
    int G[maxn][maxn], vis[maxn];
    
    int ID(char a, char b)
    {
        return (a - 'A')*2 + (b == '+' ?

    0 : 1); } void conect(char a1, char a2, char b1, char b2) { if (a1 == '0' || b1 == '0') { return ; } int u = ID(a1, a2)^1, v = ID(b1, b2); G[u][v] = 1; } bool dfs(int u) { vis[u] = -1; for (int v = 0; v < 52; v++) if (G[u][v]) { if (vis[v] == -1) return true; if (!vis[v] && dfs(v)) return true; } vis[u] = 1; return false; } bool find_cycle() { memset(vis, 0, sizeof(vis)); for (int i = 0; i < 52; i++) if (!vis[i]) { if (dfs(i)) return true; } return false; } int main() { // freopen("/Users/apple/Desktop/in.txt", "r", stdin); int n; while(scanf("%d", &n) == 1 && n) { memset(G, 0, sizeof(G)); while (n--) { char s[10]; scanf("%s", s); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) if (i != j) { conect(s[i*2], s[i*2+1], s[j*2], s[j*2+1]); } } } if (find_cycle()) printf("unbounded "); else printf("bounded "); } return 0; }



  • 相关阅读:
    帆软报表实现全选全不选的功能
    knowledge_others
    skills_kafka
    skills_operation
    problems_others
    skills_windows
    c语言标识符
    快速排序法
    字符串处理scanf("%d%*c",&n);
    Byte.parseByte(String s,int radix)的解释
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7077730.html
Copyright © 2020-2023  润新知