HDU 3231 Box Relations (三维 拓扑)

http://acm.hdu.edu.cn/showproblem.php?pid=3231

其实3维并不难处理,只是 , 如何 处理每一维 XYZ 上的 关系, 开始能想到用拓扑 就不好想, 如果没有  'I' 这个关系,可以把每个box在每一维上看做一个点,构造大小关系,但是有这个‘I',可以 把每个box的信息 分到每一维 上的两点,大小关系  a<a+n  代表一维上的两点,给出的relation  x,y,z  都是对应的一维上的关系 eg :  X 1 2   即 1+n<2

而 I 1 2  每一维上都是  1+n>2 && 1<w+n   之后根据大小关系拓扑排序,输出任意结果即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
using namespace std;
#define max(a,b) (a)>(b)? (a):(b)
#define min(a,b) (a)>(b)? (b):(a)
#define INT_MIN -0x7FFFFFFF
#define INF 100000000
#define N 1005
int n,r;
int in[5][2*N],dui[5][2*N];
vector<int> edge[5][2*N];
int ans[5][2*N];
void inser(int x,int y,int z)
{
    int i,j,k;
    in[x][z]++;
    edge[x][y].push_back(z);
}
void init()
{
    int i,j;
    memset(in,0,sizeof(in));
    for(i=1;i<=3;i++)
    {
        for(j=0;j<=2*n;j++)
        {
            edge[i][j].clear();
        }
    }
    for(i=1;i<=3;i++)
    {
        for(j=1;j<=n;j++)
        {
            inser(i,j,j+n);
        }
    }
}
int topo(int x)
{
    int i,j,k;
    int head,tail;
    head=tail=0;
    for(i=1;i<=2*n;i++)
    {
        if(in[x][i]==0)
        {
            dui[x][tail++]=i;
        }
    }
    while(head<tail)
    {
        int now=dui[x][head++];
        for(i=0;i<edge[x][now].size();i++)
        {
            int next=edge[x][now][i];
            in[x][next]--;
            if(in[x][next]==0)
            {
                dui[x][tail++]=next;
            }
        }
    }
    return tail==2*n;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int i,j,k;
    int time=0;
    while(scanf("%d%d",&n,&r)!=EOF &&(n||r) )
    {
        init();
        char ch[5];
        int a,b;
        for(i=1;i<=r;i++)
        {
            scanf("%s%d%d",ch,&a,&b);
            if(ch[0]=='I')
            {
                for(j=1;j<=3;j++)
                {
                    inser(j,b,a+n);
                    inser(j,a,b+n);
                }
            }
            else
            {
                inser(ch[0]-'X'+1,a+n,b);
            }
        }
        int flag=0;
        for(i=1;i<=3;i++)
        {
            int tem=topo(i);
            if(!tem)
            {
                flag=1;
            }
        }
        printf("Case %d: ",++time);
        if(flag) printf("IMPOSSIBLE\n");
        else
        {
            printf("POSSIBLE\n");
            for(i=1;i<=3;i++)
            {
                for(j=0;j<2*n;j++)
                {
                    ans[i][dui[i][j]]=j;
                }
            }
            for(i=1;i<=n;i++)
            {
                printf("%d %d %d %d %d %d\n",ans[1][i],ans[2][i],ans[3][i],ans[1][i+n],ans[2][i+n],ans[3][i+n]);
            }
        }
        puts("");
    }

    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值