UVA-1572 Self-Assembly(拓扑排序判断有向环)

题目:

给出几种正方形,每种正方形有无穷多个。在连接的时候正方形可以旋转、翻转。

正方形的每条边上都有一个大写英文字母加‘+’或‘-’、00,当字母相同符号不同时,这两条边可以相连接,00不能和任何边相连。

判断给出的正方形如果能无限连接下去就输出unbounded、不能就输出bounded。

思路:

这个题读完之后,一点思路都没有,看完紫书上的分析知道是用拓扑排序来判断有向环,但具体的构造还是不会……

1.将每个正方形看作一条边,在正方形每两条边上的字母(不包括00)之间连一条有向边构成一个有向图。

2.使用(2*n)^1 = (2*n+1)、(2*n+1)^1 = (2*n)。

3.利用拓扑排序来判断有没有有向环,有则输出unbounded、没有就输出bounded。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e9+7;
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = 60;
int n,mp[maxn][maxn],vis[maxn];

int getId(char a,char b) {
    return (a-‘A‘)*2+(b==‘+‘ ? 1 : 0);
}

void solve(char x1,char x2, char y1,char y2) {
    if(x1==‘0‘ || y1==‘0‘) {
        return;
    }
    int x = getId(x1, x2)^1;
    int y = getId(y1,y2);
    mp[x][y] = 1;
}

void insertG(char* str) {//建图
    for(int i = 0; i<8; i+=2) {
        for(int j = 0; j<8; j+=2) {
            if(i!=j) {
                solve(str[i],str[i+1],str[j],str[j+1]);
            }
        }
    }
}

bool dfs(int x) {
    vis[x] = 1;//正在被访问中
    for(int i = 0; i<52; i++) {
        if(mp[x][i]) {
            if(vis[i])//如果已经被访问过,就是有环
            { return true; }
            if(!vis[i] && dfs(i))//后续的递归中出现有环的情况
            {return true;}
        }
    }
    vis[x] = 0;
    return false;
}

bool topuSort() {//拓扑排序
    memset(vis,0,sizeof(vis));
    for(int i = 0; i<52; i++) {//个人理解因为可能有多个连通分量,所以每一个点都要跑一把
        if(!vis[i] && dfs(i)) { //有环
            return true;
        }
    }
    return false;//没有环
}

int main() {
    while(scanf("%d",&n)!=EOF) {
        char str[9];
        memset(mp,0,sizeof(mp));
        for(int i=0; i<n; i++) {
            scanf("%s",str);
            insertG(str);
        }
        if(topuSort()) {
            printf("unbounded\n");
        } else {
            printf("bounded\n");
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/sykline/p/10294057.html

时间: 2024-08-04 07:03:13

UVA-1572 Self-Assembly(拓扑排序判断有向环)的相关文章

hdoj 4324 Triangle LOVE【拓扑排序判断是否存在环】

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

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]

Lightoj 1003 - Drunk(拓扑排序判断是否有环 Map离散化)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1003 题意是有m个关系格式是a b:表示想要和b必须喝a,问一个人是否喝醉就看一个人是否能把所有种类的饮料喝完,能输出Yes,不能输出No: 其实就是有向图判断是否存在环,可以用拓扑排序来求 拓扑排序:每次找到一个入度为0的点加入队列,删除与之相连的边,循环操作,得到的序列就是拓扑序(前面的必须出现在后面的前面): #include<stdio.h> #include<str

拓扑排序 判断给定图是否存在合法拓扑序列 自家oj1393

1 //拓扑排序判断是否有环 2 #include<cstdio> 3 #include<algorithm> 4 #include<string.h> 5 #include<math.h> 6 #include<queue> 7 using namespace std; 8 typedef long long ll; 9 const int maxn=1e2+10; 10 int G[maxn][maxn]; 11 int in[maxn];

拓扑排序 --- 判断是否有回路

Legal or Not Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3823    Accepted Submission(s): 1738 Problem Description ACM-DIY is a large QQ group where many excellent acmers get together. It is

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)

拓扑排序判断有向图是否有回路

1 #include <iostream> 2 #include <queue> 3 #include <string> 4 using namespace std; 5 6 //表结点 7 typedef struct ArcNode{ 8 int adjvex;//该弧所指向的顶点的位置 9 ArcNode *nextarc; 10 }ArcNode; 11 12 //头结点 13 typedef struct VNode{ 14 string data;//顶点信

HDU 3342 Legal or Not(拓扑排序判断成环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3342 题目大意:n个点,m条有向边,让你判断是否有环. 解题思路:裸题,用dfs版的拓扑排序直接套用即可. 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int N=1e2+5; 6 7 int n,m; 8 int vis[N];