例题6

来源:互联网 发布:好听的淘宝会员名大全 编辑:程序博客网 时间:2024/05/21 06:48

原题连接:https://vjudge.net/problem/UVA-1572

题意:给你N个正方形,看是否拼接成一个无限拓展的图形,每个正方形的拼接规则就是相同字母且符号相反(00不能拼接)

思路:把给的正方形的边抽象成点,四个点重新组合成6条边,如果这些边构成的有向图成环,那么就是无限大平面。另(2n + 1) ^ 1 =  2n,  (2n) ^ 1 = 2 n + 1。

           还将字母数字化,A- 和 A+分别视为 0 1

Code:

#include <bits/stdc++.h>using namespace std;const int AX = 52+6;int G[AX][AX];int mark[AX];int id( char a1 , char a2 ){return ( a1 - 'A' ) *2 + ( a2 == '+' ? 1 : 0 );  }void connect( char a1 , char a2 ,char b1 ,char b2 ){ //id(a1,a2)^ 1 和id(a1,a2)是毫无疑问能够拼接的,那么又因为id(a1,a2)能够跟id(b1,b2)接,所以id(a1,a2)^ 1和id(b1,b2)也可以拼接。if( a1 == '0' || b1 == '0' ) return;int u = id( a1 , a2 ) ^ 1 ; int v = id( b1 , b2 );G[u][v] = 1;}bool dfs( int u ){mark[u] = -1 ;for( int v = 0 ; v < 52 ; v++ ){if( G[u][v] ){if( mark[v] < 0 ) return false;else if( !mark[v] && !dfs(v) ) return false;}}mark[u] = 1;return true;}bool topSort(){memset(mark,0,sizeof(mark));for( int i = 0 ; i < 52 ; i ++ ){if( !mark[i] ){if( !dfs(i) ) return false ;}}return true;}int main(){int n ;//freopen("1572.txt","r",stdin);while( ~scanf("%d",&n) && n ){memset(G,0,sizeof(G));while(n--){char s[10];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] );}}}//每个边抽象成点,那么4个点会有6种边的组合情况,即上面的for循环(j)/*connect(s[0], s[1], s[2], s[3]);            connect(s[4], s[5], s[6], s[7]);            connect(s[0], s[1], s[4], s[5]);            connect(s[0], s[1], s[6], s[7]);            connect(s[2], s[3], s[4], s[5]);            connect(s[2], s[3], s[6], s[7]);*/}if( topSort() ){cout << "bounded" << endl;}else{cout << "unbounded" << endl;}}return 0;}