Hdu 3231 Box Relations(拓扑排序)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3231

思路:拓扑排序。将每个长方体的每对面看成一条线段,将线段看成两个点,则共有3条线段,6个点。

对于一组相交关系,若两个长方体相交,当且仅当每一维中一个长方体的面插入另一个长方体的内部。

将长方体分为左右,上下,前后三维。

例如一长方形设左面为x,右面为x+n,另一长方体左面为y,右面为y+n,则在该维中坐标x<y+n,y<x+n,x<x+n,其他两维同理。

则由大小关系,分别对每一维拓扑排序即可。

#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const int maxn=2000+50;
char ch;
int n,m,x,y;
queue<int> q;
int d[3][maxn];
int tmp[3][maxn];
int ans[3][maxn];
vector<int> g[3][maxn];
int topsort(int id)
{
    int tot=0;
    while(!q.empty()) q.pop();
    for(int i=1; i<=2*n; i++)
    {
        if(!d[id][i])
        {
            //cout<<id<<" "<<i<<endl;
            tot++;
            q.push(i);
            tmp[id][tot]=i;
        }
    }
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=0; i<g[id][now].size(); i++)
        {
            int nt=g[id][now][i];
            d[id][nt]--;
            if(!d[id][nt])
            {
                tot++;
                q.push(nt);
                tmp[id][tot]=nt;
            }
        }
    }
    return (tot==2*n);
}
void init()
{
    memset(d,0,sizeof(d));
    memset(tmp,0,sizeof(tmp));
    for(int i=0; i<=2*n; i++)
        for(int j=0; j<3; j++)
            g[j][i].clear();
    for(int i=0; i<3; i++)
        for(int j=1; j<=n; j++)
        {
            g[i][j].push_back(j+n);
            d[i][j+n]++;
        }
}
int solve()
{
    for(int i=0; i<3; i++)
        if(!topsort(i)) return 0;
    for(int i=0; i<3; i++)
        for(int j=1; j<=2*n; j++)
            ans[i][tmp[i][j]]=j-1;
    return 1;
}
int main()
{
#ifdef debug
    freopen("in.in","r",stdin);
#endif // debug
    int cas=0;
    while(scanf("%d%d",&n,&m)==2&&(n||m))
    {
        init();
        printf("Case %d: ",++cas);
        for(int i=0; i<m; i++)
        {
            getchar();
            scanf("%c%d%d",&ch,&x,&y);
            if(ch=='I')
            {
                g[0][x].push_back(y+n),d[0][y+n]++;
                g[0][y].push_back(x+n),d[0][x+n]++;
                g[1][x].push_back(y+n),d[1][y+n]++;
                g[1][y].push_back(x+n),d[1][x+n]++;
                g[2][x].push_back(y+n),d[2][y+n]++;
                g[2][y].push_back(x+n),d[2][x+n]++;
            }
            else
            {
                if(ch=='X')
                    g[0][x+n].push_back(y),d[0][y]++;
                else if(ch=='Y')
                    g[1][x+n].push_back(y),d[1][y]++;
                else if(ch=='Z')
                    g[2][x+n].push_back(y),d[2][y]++;
            }
        }
        /*for(int i=0; i<3; i++)
            for(int j=1; j<=2*n; j++)
                cout<<i<<" "<<j<<" "<<d[i][j]<<endl;*/
        if(!solve()) printf("IMPOSSIBLE\n\n");
        else
        {
            printf("POSSIBLE\n");
            for(int i=1; i<=n; i++)
                printf("%d %d %d %d %d %d\n",ans[0][i],ans[1][i],ans[2][i],ans[0][i+n],ans[1][i+n],ans[2][i+n]);
            printf("\n");
        }
    }
    return 0;
}

时间: 2024-11-12 18:23:04

Hdu 3231 Box Relations(拓扑排序)的相关文章

HDU 3213 Box Relations(拓扑排序构造)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3231 题意:有n个长方体,四种限制条件.(1)I x y x和y有相交:(2)X/Y/Z  x y x的最大X/Y/Z坐标小于y的最大X/Y/Z.构造出这样的n个长方体. 思路:首先,XYZ三个方向是可以分开考 虑的.那么我们可以一个个分别求解.将每个长方体拆成左上角右下角两个点,我们假设现在考虑X方向,也即是一个长方体对应两个X方向的点,共2*n个点, 边<i,j>表示i小于j,那么首先有边&l

hdu 4857 逃生 (拓扑排序+保证最小在前面)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 74    Accepted Submission(s): 13 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前. 同时,社会是不平

HDU 4324:Triangle LOVE( 拓扑排序 )

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

HDU 4857 (反向拓扑排序 + 优先队列)

题意:有N个人,M个优先级a,b表示a优先于b,并且每个人有个编号的优先级,输出顺序. 思路来自:与PKU3687一样 在基本的拓扑排序的基础上又增加了一个要求:编号最小的节点要尽量排在前面:在满足上一个条件的基础上,编号第二小的节点要尽量排在前面:在满足前两个条件的基础上,编号第三小的节点要尽量排在前面--依此类推.(注意,这和字典序是两回事,不可以混淆.) 如图 1 所示,满足要求的拓扑序应该是:6 4 1 3 9 2 5 7 8 0. 图 1 一个拓扑排序的例子 一般来说,在一个有向无环图

hdu 4857 逃生(拓扑排序逆序 + 优先队列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题意:有编号 1 - n 的 n 个人逃生,编号越小的人越有钱, 在满足 m 个前提的条件下要尽可能早的逃脱 .m个前提,对于每个前提 a , b,代表 a 要早于 b逃脱. 思路: (1)这题可以理解为有钱的人优先级越高,所以可以用优先队列. (2)但是要注意这道题和字典序升序的区别. eg:5 1 5 1 按照字典序的答案:2 3 4 5 1,    本题答案: 5 1 2 3 4. 因为

HDU 5438 Ponds (拓扑排序+DFS)2015 ACM/ICPC Asia Regional Changchun Online

[题目链接]:click here~~ [题目大意]: 题意:在一个无向图中有 p 个点, m 条边,每个点有一个值 vi .不断的删去度数小于2的点直到不能删为止.求新图中所有点个数为奇数的连通分量的点值的和. 1<p<10^4,1<m<10^5 [思路]删边考虑类似拓扑排序的写法,不过topsort是循环一遍1到n结点入度为0的结点,然后加入到队列中,这里只要改一下度数小于等于1,最后DFS 判断一下 挫挫的代码: /* * Problem: HDU No.5438 * Run

HDU 4857 逃生(拓扑排序逆向+邻接表存图)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4857 题目: Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平等的,这些人有的穷有的富.1号最富,2号第二富,以此类推.有钱人就贿赂负责人,所以他们有一些好处. 负责人现在可以安排大家排队的顺序,由于收了好处,所以他要让1号尽量靠前,

hdu 4857 逃生 (拓扑排序+优先队列)

逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 688    Accepted Submission(s): 190 Problem Description 糟糕的事情发生啦,现在大家都忙着逃命.但是逃命的通道很窄,大家只能排成一行. 现在有n个人,从1标号到n.同时有一些奇怪的约束条件,每个都形如:a必须在b之前.同时,社会是不平

hdu 4857 逃生(拓扑排序)

本题链接:点击打开链接 本题大意: 输入一个T,表示有T组测试输出:然后输入和M,表示有N个点,M条有向边,然后输入每条边的两个点a,b:表示a必须在b前:输出一种符合要求的拓扑序列. 解题思路: 最先输出的是排在最前面的,所以我想的是输入a,b,将b入度自加,然后用拓扑排序,从小到大进行查找,先找到的入度为零的点就输出,然后更新各点.因为本题范围要求比较大,所以就不能使用二维数组来建图,要使用链表.但我也不清楚发生了什么,按照这样的思路得到的答案是错误的,参考别人的代码,发现别人都是反向建图,