uva 1572 self-assembly ——yhx

来源:互联网 发布:烟花算法程序 编辑:程序博客网 时间:2024/04/30 15:03

 1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 int map[60][60],cnt[60]; 6 queue<int> q; 7 char s[10]; 8 int main() 9 {10     int i,j,k,m,n,p,t,x,y,z,w,temp[5];11     while (~scanf("%d",&n))12     {13         memset(map,0,sizeof(map));14         memset(cnt,0,sizeof(cnt));15         while (!q.empty()) q.pop();16         for (i=1;i<=n;i++)17         {18             scanf("%s",s);19             t=0;20             for (j=0;j<=6;j+=2)21               if (s[j]!='0')22               {23                   if (s[j+1]=='+')24                     temp[++t]=(s[j]-'A')*2;25                   else26                     temp[++t]=(s[j]-'A')*2+1;27               }28             for (j=1;j<=t;j++)29               for (k=j+1;k<=t;k++)30                 map[temp[j]^1][temp[k]]=map[temp[k]^1][temp[j]]=1;31         }32         for (i=0;i<=51;i++)33           for (j=0;j<=51;j++)34             if (map[i][j]) cnt[j]++;35         t=0;36         for (i=0;i<=51;i++)37           if (!cnt[i])38           {39               t++;40               q.push(i);41           }42         while (!q.empty())43         {44             x=q.front();45             q.pop();46             for (i=0;i<=51;i++)47               if (map[x][i])48               {49                   cnt[i]--;50                   if (!cnt[i])51                   {52                       q.push(i);53                       t++;54                 }55               }56         }57         if (t<52) printf("unbounded\n");58         else printf("bounded\n");59     }60 }

算法实现其实很简单,关键需要想明白。

只要边上的标号重复,那就一定可以通过不断的翻转无限延伸。

于是我们可以把每种标号看成一个点,每个正方形看成若干条边(比如,正方形上有两条边标号分别是A+,B-,那就分别连A-→B-,B+→A+,表示如果目前有一条边缘是A-,那么就可以有一个边缘是B-。

如果图中存在环,那么就说明标号会重复了,也就是会无限延伸。

拓扑排序或DFS均可。

小技巧:A+记为0,A-记为1,B+记为2,B-记为3,以此类推。每次求相反符号的标号只需^1。

0 0
原创粉丝点击