标签:
题目抽象:有n种正方形。每种的数量无穷多。给出正方形每边的标号。 给出正方形的连接规则。 问是否可以连接出无界的图形。
思路:拓扑排序,以边上标号为点,正方形为边,拓扑图中存在有向环时unbounded,否则bounded;
另外一个值得学习的地方是编号的时候,A+和A-可分别变为2n+1和2n,然后一个重要的关系要利用好就是(2n+1)^1 = 2n,2n^1 =(2n+1),可以很容易的进行A+和A-的变换。
思维难度有点大。初次接触很难做出来。题解里包含一些技巧。需要好好消化。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 const int MS=52; 8 9 int edges[MS][MS]; 10 int c[MS]; 11 12 int ID(char c1,char c2) 13 { 14 return (c1-‘A‘)*2+(c2==‘+‘?0:1); 15 } 16 17 // (2n+1)^1 = 2n,2n^1 = (2n+1) 利用这个性质很好处理A+ A- 18 void connect(char a1,char a2,char b1,char b2) 19 { 20 if(a1==‘0‘||b1==‘0‘) 21 return ; 22 int u=ID(a1,a2)^1; 23 int v=ID(b1,b2); 24 edges[u][v]=1; 25 } 26 27 bool dfs(int u) 28 { 29 c[u]=-1; 30 for(int v=0;v<MS;v++) 31 { 32 if(edges[u][v]) 33 { 34 if(c[v]<0) 35 return true; 36 else if(!c[v]&&dfs(v)) 37 return true; 38 } 39 } 40 c[u]=1; 41 return false; 42 } 43 44 bool find_cycle() 45 { 46 memset(c,0,sizeof(c)); 47 for(int i=0;i<MS;i++) 48 { 49 if(!c[i]) 50 if(dfs(i)) 51 return true; 52 } 53 return false; 54 } 55 56 int main() 57 { 58 int n; 59 while(scanf("%d",&n)!=EOF) 60 { 61 memset(edges,0,sizeof(edges)); 62 while(n--) 63 { 64 char str[MS]; 65 scanf("%s",str); 66 for(int i=0;i<4;i++) 67 for(int j=0;j<4;j++) 68 if(i!=j) 69 { 70 connect(str[i*2],str[i*2+1],str[j*2],str[j*2+1]); 71 } 72 } 73 if(find_cycle()) 74 printf("unbounded\n"); 75 else 76 printf("bounded\n"); 77 } 78 return 0; 79 }
标签:
原文地址:http://www.cnblogs.com/hutaishi/p/4535626.html