HDU3231拓扑排序

Box Relations

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1334    Accepted Submission(s): 540
Special Judge

Problem Description

There are n boxes C1, C2, ..., Cn in 3D space. The edges of the boxes are parallel to the x, y or z-axis. We provide some relations of the boxes, and your task is to construct a set of boxes satisfying all these relations.

There are four kinds of relations (1 <= i,j <= ni is different from j):

    • I i j: The intersection volume of Ci and Cj is positive.
    • X i j: The intersection volume is zero, and any point inside Ci has smaller x-coordinate than any point inside Cj.
    • Y i j: The intersection volume is zero, and any point inside Ci has smaller y-coordinate than any point inside Cj.
  • Z i j: The intersection volume is zero, and any point inside Ci has smaller z-coordinate than any point inside Cj.

.

Input

There will be at most 30 test cases. Each case begins with a line containing two integers n (1 <= n <= 1,000) and R (0 <= R <= 100,000), the number of boxes and the number of relations. Each of the following R lines describes a relation, written in the format above. The last test case is followed by n=R=0, which should not be processed.

Output

For each test case, print the case number and either the word POSSIBLE or IMPOSSIBLE. If it‘s possible to construct the set of boxes, the i-th line of the following nlines contains six integers x1, y1, z1, x2, y2, z2, that means the i-th box is the set of points (x,y,z) satisfying x1 <= x <= x2, y1 <= y <= y2, z1 <= z <= z2. The absolute values of x1, y1, z1, x2, y2, z2 should not exceed 1,000,000.

Print a blank line after the output of each test case.

Sample Input

3 2

I 1 2

X 2 3

3 3

Z 1 2

Z 2 3

Z 3 1

1 0

0 0

Sample Output

Case 1: POSSIBLE

0 0 0 2 2 2

1 1 1 3 3 3

8 8 8 9 9 9

Case 2: IMPOSSIBLE

Case 3: POSSIBLE

0 0 0 1 1 1

Source

2009 Asia Wuhan Regional Contest Hosted by Wuhan University

题意:

给出n个立方体之间的位置关系,I a,b 表示a和b相交,X a,b 表示a的x坐标都小于b的x坐标,输出符合条件的立方体的坐标范围

代码:

//把立方体的六个面看成6个点,每个立方体都有自己的约束条件(x1<x2,y1<y2,z1<z2),立方体之间又有
//约束条件,这样三维坐标分成三部分建图,拓扑排序,排在后面的比排在前面的多加1单位长度.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn=2005;
int n,m,in[3][maxn],val[3][maxn];
vector<int>g[3][maxn];
void init()
{
    for(int i=0;i<3;i++){
        for(int j=1;j<=n*2;j++){
            in[i][j]=val[i][j]=0;
            g[i][j].clear();
        }
    }
    for(int i=0;i<3;i++){
        for(int j=1;j<=n;j++){
            in[i][j+n]++;
            g[i][j].push_back(j+n);
        }
    }
}
bool topo()
{
    for(int i=0;i<3;i++){
        queue<int>q;
        int cnt=0;
        for(int j=1;j<=n;j++)
        if(in[i][j]==0){
            val[i][j]=cnt++;
            q.push(j);
        }
        while(!q.empty()){
            int a=q.front();q.pop();
            for(int j=0;j<(int)g[i][a].size();j++){
                int b=g[i][a][j];
                val[i][b]=max(val[i][b],val[i][a]+1);//!
                if(--in[i][b]==0){
                    q.push(b);cnt++;
                }
            }
        }
        if(cnt!=n*2) return 0;
    }
    return 1;
}
int main()
{
    int cas=0;
    while(scanf("%d%d",&n,&m)&&(n+m)){
        init();
        char ch[5];int a,b;
        while(m--){
            scanf("%s%d%d",ch,&a,&b);
            if(ch[0]==‘I‘){
                for(int i=0;i<3;i++){
                    in[i][a+n]++;g[i][b].push_back(a+n);
                    in[i][b+n]++;g[i][a].push_back(b+n);
                }
            }
            else if(ch[0]==‘X‘){
                in[0][b]++;g[0][a+n].push_back(b);
            }
            else if(ch[0]==‘Y‘){
                in[1][b]++;g[1][a+n].push_back(b);
            }
            else{
                in[2][b]++;g[2][a+n].push_back(b);
            }
        }
        printf("Case %d: ",++cas);
        if(topo()){
            printf("POSSIBLE\n");
            for(int i=1;i<=n;i++)
                printf("%d %d %d %d %d %d\n",val[0][i],val[1][i],val[2][i],val[0][i+n],val[1][i+n],val[2][i+n]);
        }
        else printf("IMPOSSIBLE\n");
        printf("\n");
    }
    return 0;
}
时间: 2024-10-15 08:21:35

HDU3231拓扑排序的相关文章

hdu3231 (三重拓扑排序)

这道题算是我拓扑排序入门的收棺题了,卡了我好几天,期间分别犯了超时,内存溢出,理解WA,细节WA,格式WA…… 题目的意思大概是在一个三维坐标系中,有一大堆矩形,这些矩形的每条棱都与坐标轴平行. 这些矩形有4种情况—— 1. 有重合部分(I a b) 表示a与b重合: 2. a的x坐标大于b的x坐标(X a b),表示a的最大的x坐标大于b的最小的x坐标: 3. (Y a b)y坐标,同上: 4. (Z a b)z坐标,同上: 也就是说,我们可以把每个矩形ai按照三个方向分解,分别为——平行于x

拓扑排序讲解

在这里我们要说的拓扑排序是有前提的 我们在这里说的拓扑排序是基于有向无环图的!!!. (⊙o⊙)…我所说的有向无环图都知道是什么东西吧.. 如果不知道,我们下面先来来说说什么是有向无环图. 所谓有向无环图,顾名思义是不存在环的有向图(至于有向图是什么不知道的在前面我们有一个图论讲解上都有). 点的入度:以这个点为结束点的边数. 点的出度:以这个点为出发点的边的条数. 拓扑序就是对于一个节点的一个排列,使得(u,v)属于E,那么u一定出现在v的前面.然而拓扑排序就是一个用来求拓扑序的东西. 对于左

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

7-9-有向图无环拓扑排序-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第7章  图 - 有向无环图拓扑排序 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceStack.c.ALGraph.c    

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

hdu1285(拓扑排序)

这道题要求没有输赢关系的两个元素必须按照升序输出,有输赢关系的,赢得在输的前面,所以用队列或者栈来降低时间复杂度的优化过的拓扑排序会出错. 比如这组输入 5 3 1 2 2 3 4 5 至少我写的两种拓扑排序都wa了.但是不用队列或者栈来优化的话, 1.每次都从头至尾扫描一遍,找到一个没标记过的节点, 2.将它标记 3.然后删除从它出来的每条边. 重复这三个操作,加标记的次序,就是题目要的答案. 下面的代码中用到了队列,但只是用来保存答案而已.并没有用它优化的意思. #include <iost

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)

NOJ 2015年陕西省程序设计竞赛网络预赛(正式赛)(忙碌的选课系统-拓扑排序注意重边)

D - 忙碌的选课系统 Time Limit: 10000 ms        Memory Limit: 65536 KB Submit Description 每学期末,都是万众瞩目的选课时间,由于人数过多,某学校的服务器常常被无数的学生挤的爆掉,这是,教务系统大人说,你们选个课都这么慢,居然还怪我们.于是,每次教务系统都会在服务器快要瘫痪前关闭它.在无数学生的强烈抗议下,教务系统妥协了,再给每个人一次机会,但他让我们用最快的方式决定该选的课程,选上后就退出. 这让大一学渣狗犯了难,在新的选

POJ1420 Spreadsheet(拓扑排序)注意的是超内存

Spreadsheet Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 617   Accepted: 290 Description In 1979, Dan Bricklin and Bob Frankston wrote VisiCalc, the first spreadsheet application. It became a huge success and, at that time, was the ki