uvalive 6393(uva 1572) Self-Assembly 拓扑排序

题意:

给出一些正方形,这些正方形的每一条边都有一个标号,这些标号有两种形式:1.一个大写字母+一个加减号(如:A+, B-, A-......), 2.两个0(如:00);这些正方形可以随意翻转和旋转,当两个正方形通过旋转或翻转,使得他们的公共边为相同大写字母并且符号相反时,他们就可以彼此结合拼在一起,现在给出n中正方形,每种正方形有无限多种,问这些正方形能否拼成一个无限大的结构。

题解:

容易想到,要使这些正方形形成无限大地结构,那么这些正方形通过拼接后一定能循环(即通过不断地拼接出现了和以前相同地正方形),那么就可以通过判断将这些正方形地所有可能地拼接方式连有向边,然后判断是否有有向环,即可通过拓扑排序来判断。

代码:

#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 52 + 10;
int G[maxn][maxn], vis[maxn];

int ID(char a, char b)
{
    return (a - 'A')*2 + (b == '+' ? 0 : 1);
}
void conect(char a1, char a2, char b1, char b2)
{
    if (a1 == '0' || b1 == '0')
    {
        return ;
    }
    int u = ID(a1, a2)^1, v = ID(b1, b2);
    G[u][v] = 1;
}
bool dfs(int u)
{
    vis[u] = -1;
    for (int v = 0; v < 52; v++) if (G[u][v])
    {
        if (vis[v] == -1) return true;
        if (!vis[v] && dfs(v)) return true;
    }
    vis[u] = 1;
    return false;
}
bool find_cycle()
{
    memset(vis, 0, sizeof(vis));
    for (int i = 0; i < 52; i++) if (!vis[i])
    {
        if (dfs(i)) return true;
    }
    return false;
}
int main()
{
 //   freopen("/Users/apple/Desktop/in.txt", "r", stdin);
    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)
                {
                    conect(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;
}
时间: 2025-01-12 08:01:31

uvalive 6393(uva 1572) Self-Assembly 拓扑排序的相关文章

UVA 1572 Self-Assembly(拓扑排序)

1 // 把一个图的所有结点排序,使得每一条有向边(u,v)对应的u都排在v的前面. 2 // 在图论中,这个问题称为拓扑排序.(toposort) 3 // 不难发现:如果图中存在有向环,则不存在拓扑排序,反之则存在. 4 // 不包含有向环的有向图称为有向无环图(DAG). 5 // 可以借助DFS完成拓扑排序:在访问完一个结点之后把它加到当前拓扑序的首部. 6 7 int c[maxn]; 8 int topo[maxn],t; 9 bool dfs(int u) 10 { 11 c[u]

UVa 10305 - Ordering Tasks 拓扑排序题解

Topological Sort题解.本题是简单的入门题目. Topological Sort的思想很简单,就是按没有入度的点,先输出,然后删除这个点的出度.然后输出下一组没有入度的点. 如何实现也是很简单的: 这里使用邻接表,建图的时候反过来建图,建立一个入度邻接表. 然后使用一个vis数组,记录访问过的节点,也可以根据这个信息知道哪些是已经输出的点,这个时候这些点的入度可以不算为当前入度了. #include <stdio.h> #include <vector> using

uva 10305 Ordering Tasks(拓扑排序)

拓扑排序,不用判断是否有环,dfs挺简单的 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> int map[105][105]; int visit[105]; int c[105]; int n,m,t; void dfs(int x) { visit[x] = 1; for(int i=1; i<=n; i++) { if(!visit[i]&&map[i][x]==1)

UVa 10305 - Ordering Tasks (拓扑排序裸题)

John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed. Input The input will consist of several instances of the problem. Each instance begins with

UVALive - 5906 Smoking gun(差分约束系统+拓扑排序)

题目大意:给出N个人的坐标和M个听到枪声的顺序,问是否有一个开枪顺序能满足着M个条件,是一个还是多少? 解题思路:典型的差分约束系统,设第i个人开枪时间为ti 假设a先听到b的枪声,再听到c的枪声 那么就要满足一个条件 tb + dis(a,b) <= tc + dis(a,c)(这里本来都要除以音速的,但此处可以省略) 由这个不等式构造边,具体构造就不说了,了解差分约束系统的都会构造,如果不会,证明你还不太了解 接着判断,如果有环,表明条件不可能全部成立 在条件成立的情况下,拓扑一下,如果拓扑

UVA 1423 Guess 【拓扑排序】

题目链接:http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=36239 题意:给你序列的区间和的正负,要求构造一组序列满足条件. 转换为前缀和,进行拓扑序列. 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<queue> using names

UVA 10305- Ordering Tasks(经典拓扑排序)

Problem F Ordering Tasks Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have al

UVa 1572 Self-Assembly (构造+拓扑排序。。。。。)

题意:给定n个带标号的正方形,标号要么是一个大写字母加一个+或-,要么是00, 当且仅当大写字母相同并且符号相反时可以连接,问你给定的能不能拼成一个无限大的的东西. 析:说实话,真心没有看出来是拓扑排序,后来知道是,可是还是不会写. 既然要拼成无限大,那么只要拼的时候拼出一个环来,又由于每个是无限多的,那么可以一直重复, 就能拼起来无限大的东西,把每个正方形看成一条边,那么不就是一个拓扑排序,看看能不能找到一个环么, 如果能找到,那么就可以,找不到,就不可以.注意的是正方形可以从四面都拼,所以要

UVALive 6467 Strahler Order 拓扑排序

这题是今天下午BNU SUMMER TRAINING的C题 是队友给的解题思路,用拓扑排序然后就可以了 最后是3A 其中两次RE竟然是因为: scanf("%d",mm); ORZ 以后能用CIN还是CIN吧 QAQ 贴代码了: 1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <math.h> 5 #include <iostre