【建图+拓扑判环】BZOJ3953: [WF2013]Self-Assembly

Description

自动化学制造(Automatic Chemical Manufacturing,简称ACM)正在对一个叫自组装(self-assembly)的过程进行实验。在这个过程中,有着天然相互吸引力的分子被混合在溶液中,任由它们聚集组合成更大的结构。但是有一个问题随之出现:有时候,分子们会把自身组合成一个无限大的结构体,以至于把容器撑爆。

  你需要写一个程序来判断一个给定的分子集合是否可能组合成一个无限大的结构体。为了使问题简化,你可以作以下两个假设:

  1. 问题被限制在二维平面上。

  2. 分子集合中的每个分子都被表示成一个正方形。其中正方形的四条边分别代表分子间相连接的四个表面。

  你将从数据中得到每种分子的描述。每种分子有四个连接标识来分别表示每条边能与另外分子的哪种边相连。连接标识有两种:

  ● 一个大写字母(A,…,Z)加上一个 ‘+’ 号或一个 ‘-’ 号。两条边能并在一起当且仅当两者的字母相等且符号相反。比方说,‘A+’ 与 ‘A-’ 兼容,但与 ‘A+’ 或 ‘B-’ 不兼容

  ● 两个零 ‘00’。这条边将不和任意一条边兼容(包括‘00’)。

  假设每种分子都有无限个,并且每个分子都可以旋转和翻转。当分子将自身组成一个结构体时,相互贴合的边必须能够相互兼容,当然,无论边的连接标识是什么,它都可以不与另外边贴合。

  图 1 是一个由三种分子组成的一个有限的结构体(它们也有可能组成另外的有限结构体)。

Solution

这道题关键是要想到怎么建图

把元素看做点

正方形是使这些点联系的媒介也就是边

a和b是一个正方形上两个元素

那么a可以通过b到op(b)

就这么建图,对于无穷大这种设问,显然是问有无环

对于有向图,拓扑排序即可

存在环就可以理解为它们总是可以通过旋转翻折拼在一起

大概比较神奇

紫书例题

Code

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=55;
 5
 6 int r[maxn],del[maxn],G[maxn][maxn];
 7 char s[10];
 8 int n,a[5];
 9
10 int idx(int p){
11     if(s[p*2]==‘0‘) return -1;
12     int ret=s[p*2]-‘A‘;
13     ret*=2;
14     if(s[p*2+1]==‘-‘) ret++;
15     return ret;
16 }
17
18 int topu(){
19     for(int t=0;t<52;t++){
20         int flag=0;
21         for(int i=0;i<52;i++)
22             if(!del[i]&&!r[i]){
23                 del[i]=1;
24                 for(int j=0;j<52;j++)
25                     if(G[i][j]) r[j]--;
26                 flag=1;
27                 break;
28             }
29         if(!flag) return 0;
30     }
31     return 1;
32 }
33
34 int main(){
35     scanf("%d",&n);
36     for(int i=1;i<=n;i++){
37         scanf("%s",s);
38         for(int j=0;j<4;j++)
39             a[j]=idx(j);
40
41         for(int j=0;j<4;j++)
42             for(int k=j+1;k<4;k++)
43             if(a[j]!=-1&&a[k]!=-1&&j!=k){
44                 if(!G[a[j]][a[k]^1]) r[a[k]^1]++;//一开始少了if以至于入度比实际的大
45                 G[a[j]][a[k]^1]=1;
46                 if(!G[a[k]][a[j]^1]) r[a[j]^1]++;
47                 G[a[k]][a[j]^1]=1;
48             }
49     }
50
51     if(topu()) printf("bounded");
52     else printf("unbounded");
53     return 0;
54 }
时间: 2024-11-10 00:52:14

【建图+拓扑判环】BZOJ3953: [WF2013]Self-Assembly的相关文章

HDU4857——逃生(反向建图+拓扑排序)

逃生 Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一

SDNU 1089.拓扑排序(拓扑判环小顶堆)

Description 给定一个有向图,若图无环,则将其进行拓扑排序并输出,否则输出IMPOSABLE. Input 第一行为两个整数n(1<=n<=1000).m(1<=m<=100000): 之后m行,每行两个整数a.b(0 < a, b <= n)表示一条从a到b的有向边. Output 若存在环,输出IMPOSABLE,否则输出一行用一个空格隔开的拓扑排序的结果,若存在多个结果,输出字典序最小的. Sample Input 5 4 1 2 2 3 3 4 4 5

hdu 4324 Triangle LOVE(拓扑判环)

Triangle LOVE Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3603    Accepted Submission(s): 1416 Problem Description Recently, scientists find that there is love between any of two people. Fo

POJ 3687 反向建图+拓扑

Labeling Balls Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11146   Accepted: 3192 Description Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that: No two balls share

hdu 4857 逆向建图+拓扑排序 ***

题意:糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行.现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处.负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,如果此时还有多种情况,就再让2号尽量靠前,如果还有多种情况,就让3号尽量靠前,以此类推.那么你就要安排大家的顺序.我们保证一定有解. 链接:点我 题目

牛客练习赛11 B trie树+拓扑判环 E 分治求平面最近点对

牛客练习赛11 B  假的字符串题意:给定n个字符串,互不相等,你可以任意指定字符之间的大小关系(即重定义字典序),求有多少个串可能成为字典序最小的串,并输出它们. tags:好题 对于一个字符串, 1]如有其它字符串是它的前缀,那肯定不可能.这个直接用字典树处理就可以. 2]但如果以这个字符串为最小,怎么判定其它字符串不会矛盾呢? 其实矛盾的情况详细一点说是: 比如要以  abcd 为最小, 但又有另一个字符串 aba ,这就矛盾了. 对这种情况,在跑字典树的时候,我们对有相同父亲结点的多个儿

[POI2015][bzoj4383] Pustynia [线段树优化建图+拓扑排序]

题面 bzoj权限题传送门 luogu传送门 思路 首先,这个题目显然可以从所有小的点往大的连边,然后如果没环就一定可行,从起点(入读为0)开始构造就好了 但是问题来了,如果每个都连的话,本题中边数是$O(n^2)$级别的,显然会挂 发现两条性质: 1.所有的限制条件中,给定的总点数不超过3e5个 2.是一个点比一段区间大 第二个条件决定了我们可以利用线段树优化建图,而第一个条件告诉了我们,本题的总边数应该是$sumk\astlog_2n$级别的 那么就做完了 注意拓扑排序的时候有个技巧,把连向

[bzoj5017][Snoi2017]炸弹 tarjan缩点+线段树优化建图+拓扑

5017: [Snoi2017]炸弹 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 608  Solved: 190[Submit][Status][Discuss] Description 在一条直线上有 N 个炸弹,每个炸弹的坐标是 Xi,爆炸半径是 Ri,当一个炸弹爆炸时,如果另一个炸弹所在位置 Xj 满足: Xi?Ri≤Xj≤Xi+Ri,那么,该炸弹也会被引爆. 现在,请你帮忙计算一下,先把第 i 个炸弹引爆,将引爆多少个炸弹呢? Inp

Self-Assembly 图论 建图+拓扑

Self-Assembly 题目抽象:有n种正方形.每种的数量无穷多.给出正方形每边的标号.  给出正方形的连接规则.  问是否可以连接出无界的图形. 思路:拓扑排序,以边上标号为点,正方形为边,拓扑图中存在有向环时unbounded,否则bounded: 另外一个值得学习的地方是编号的时候,A+和A-可分别变为2n+1和2n,然后一个重要的关系要利用好就是(2n+1)^1 = 2n,2n^1 =(2n+1),可以很容易的进行A+和A-的变换. 思维难度有点大.初次接触很难做出来.题解里包含一些