UVA 1572 Self-Assembly

来源:互联网 发布:结婚线路图制作软件 编辑:程序博客网 时间:2024/05/21 06:52

拓扑排序。
题意:有n种边上带标号的正方形。每条边上的标号为一个大写字母带个‘+’号或‘-’号,或为‘00’,当两条边的字母相同且符号相反时,两条边能拼在一起,
(00不能和任何边拼接),正方形有无数种,并且可以旋转和翻转,判断是否能组成一个无限大的结构。
分析:只要有一条边无限长就可以。把标号看成点,(一共有A+~Z+和A-~Z-这52种),正方形看作边,构造一个有向图,进行拓扑排序,只要图中有环就可以无限延伸。
代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>using namespace std;const int maxn = 50 + 5;int c[maxn], g[maxn][maxn];int id(char a1, char a2) //给每个标号分配id{    return (a1 - 'A') * 2 + (a2 == '+' ? 0 : 1);}void connect(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){    c[u] = -1;    for(int v = 0; v < 52; v++)    {        if(g[u][v])        {            if(c[v] < 0) return false;            else if(!c[v] && !dfs(v)) return false;        }    }    c[u] = 1;    return true;}bool toposort(){    memset(c, 0, sizeof(c));    for(int u = 0; u < 52; u++)    {        if(!c[u])        {            if(!dfs(u)) return false;        }    }    return true;}int main(){    int n;    while(cin >> n)    {        memset(g, 0, sizeof(g));        string s;        for(int k = 1; k <= n; k++)        {            cin >> s;            for(int i = 0; i < 4; i++)            {                for(int j = 0; j < 4; j++)                {                    if(i != j) connect(s[i*2], s[i*2+1], s[j*2], s[j*2+1]);                }            }        }        if(toposort())   cout << "bounded" << endl;        else cout << "unbounded" << endl;    }    return 0;}


原创粉丝点击