UVa1572 Self-Assembly

题目传送门

UVa1572 Self-Assembly

题解

——还是属于图论建模吧。说实话不看分析可能还真做不出来。像zzq神犇说的图论一般都是考建模。
——可以把能接在一起的建边,比如说有一个正方形是A+00B+A+,那么就将B+与—>A+所对应的点A-连接(貌似是有向边)。这样一来就是52个点的图。要找出无穷大的结构,必定是有循环节的,所以去找环啦。但是找有向环我却神奇的忘了方法(一定是把scc学的半懂导致的后果)。其实想想好像只用标记在栈中的和已经访问过的节点,比如前者标为-1,后者标为1,然后碰到-1的点就有环啦。(弱弱的邻接矩阵存边)

代码

//真是又丑又长

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=60;
int n;
int G[maxn][maxn];
int Clock[maxn];
bool dfs(int x) 
{
    Clock[x]=-1;
    for(int i=1; i<=52; i++)
        if(G[x][i]) 
        {
            if(Clock[i]==-1)   return true;
            else if(!Clock[i]&&dfs(i))return true;
        }
    Clock[x]=1;
    return false;
}

void solve() {
    char c1,c2,s[10];
    memset(G,0,sizeof(G));
   {
        int u[5]= {0,0,0,0,0};
        scanf("%s",s);
        for(int j=1; j<=4; j++) 
        {
            c1=s[(j-1)*2];
            c2=s[(j-1)*2+1];
            if(c1!='0'&&c2!='0') 
            {
                if(c2=='-') u[j]=c1-'A'+1;
                else u[j]=c1-'A'+1+26;
            }
        }
        for(int j=1; j<=4; j++)
            if(u[j])
                for(int k=1; k<=4; k++)
                    if(u[k]&&j!=k) 
                    {
                        G[u[j]>26?u[j]-26:u[j]+26][u[k]]=1;
                    }

    }
    memset(Clock,0,sizeof(Clock));
    for(int i=1; i<=26*2; i++)
        if(!Clock[i])  
            if(dfs(i)) 
            {
                printf("unbounded\n");
                return ;
            }
    printf("bounded\n");
    return ;
}

int main() {
    while(scanf("%d",&n)==1)
        solve();
    return 0;
}

你可能感兴趣的:(UVa1572 Self-Assembly)