题目链接:
UVA - 1572
紫书上面的题,用到了拓扑排序,学习一下书中给的代码,见注释.
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int ID(char a1,char a2){
return (a1 - 'A') * 2 + (a2 == '+' ? 0 : 1);
}
int G[52+1][52+1];
void connect(char a,char b,char c,char d){
if(a == '0' || c == '0')
return ;
G[ID(a,b) ^ 1][ID(c,d)] = 1; //对第一个编号做异或运算,这样就等于当它作为被连接的编号
//这样就可以用下面的dfs判断是否构成一个环
}
int c[52+1];
bool dfs(int u){
c[u] = -1;
for(int v=0;v<52;v++){
if(G[u][v]){
if(c[v] < 0) //说明v比u先进行dfs,但v依然连着u,构成环
return true;
else if(!c[v] && dfs(v)) //说明v还没有进行dfs,进入递归
return true;
}
}
c[u] = 1; //说明u已经dfs完毕
return false;
}
bool find_cycle(){
memset(c,0,sizeof(c));
for(int i=0;i<52;i++){
if(!c[i])
if(dfs(i))
return true; //构成环,说明无界
}
return false;
}
int main(){
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){
connect(s[i*2],s[i*2+1],s[j*2],s[j*2+1]);
}
}
}
if(find_cycle()) printf("unbounded\n");
else printf("bounded\n");
}
return 0;
}
此题比较难懂的地方为转换为有向环的方法,异或运算很巧妙,可举简单的例子思考明白。