题意:存在n种边上带标号的正方形,每条边的标号要么为一个大写字母和一个加号或减号(相同字母符号相反可以匹配),要么为00(无法匹配),每种正方形不限制数量,而且可以旋转或者翻转,求这些正方形能否无限地组合下去。
分析:由于正方形数目不限,可以将正方形边上的符号看为点,正方形看做边,则可以根据正方形的边符号与符号的匹配规则构成一个有向图。则当且仅当途中存在有向环时有解。只需做一次拓扑排序即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
#include<sstream>
#include<queue>
#include<cctype>
using namespace std;
#define MAX 53
int G[MAX][MAX];
int c[MAX];
bool dfs(int u) {
c[u] = -1;
for(int v=1;v<MAX;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=1;u<max u="" if="" c="" dfs="" return="" false="" true="" int="" rev="" 0=""> 26 ? u-26:u+26;
}
int main() {
int N;
while(~scanf("%d",&N) && N) {
char str[10];
int k[53];
memset(k,0,sizeof(k));
memset(G,0,sizeof(G));
while(N--) {
scanf("%s",str);
int a[4];
for(int i=0;i<8;i+=2)
if(str[i+1] == '+')
a[i/2] = str[i] - 'A' + 27;
else if(str[i+1] == '-')
a[i/2] = str[i] - 'A' + 1;
else a[i/2] = 0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(i != j)
G[a[i]][rev(a[j])] = 1;
}
if(toposort())
printf("bounded\n");
else
printf("unbounded\n");
}
return 0;
}
</max></cctype></queue></sstream></map></string></vector></cstring></algorithm></iostream></cstdio>