HDU-3231 Box Relations(三维拓扑排序)

本文介绍了HDU-3231 Box Relations问题,这是一道涉及三维拓扑排序的构造题。文章讨论了如何处理长方体的相互关系,对每一维进行拓扑排序,并分享了作者的编程经验,包括初始错误和修正后的解决方案。
摘要由CSDN通过智能技术生成

Box Relations

HDU-3231

构造题
有n个长方体,满足以下要求:
I i, j : i, j不相交
X i, j : i的x维度上的坐标都小于j的x维度上的坐标
Y,Z 同理

对每一维分别进行拓扑排序。
注意:
1、对每一维,对于长方体i,都天然满足xi1 < xi2, yi1 < yi2,zi1 < zi2。
2、对与I i, j:i, j 不相交,即两个长方体中,某一个长方体的右面一定大于另一个长方体的左面,这样有两条语句:xi1 < xj2, xi2 > xj1,两条语句缺一不可。

我的代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3 + 5;
const int maxm = 1e5 + 5;
int n, m;
char ch;
int a, b;
int in[3][maxn], path[3][maxn], ans[3][maxn];
vector<int> e[3][maxm];

void init(){
    for(int j = 0; j < 3; j++){
        for(int i = 1; i <= 2*n; i++){
            in[j][i] = 0; e[j][i].clear();
        }
    }
}

int topsort(){
    for(int t = 0; t < 3; t++){
//        priority_queue< int,vector<int>,greater<int> > s;
        queue<int>s;
        for(int i = 1; i <= 2 * n; i++){
            if(in[t][i] == 0)
                s.push(i);
        }
        int cnt = 0;
        while(!s.empty()){
            int x = s.front();
            s.pop();
            path[t][x] = cnt++;
//            path[t][++cnt] = x;
            for(int i = 0; i < e[t][x].size(); i++){
                int y = e[t][x][i];
                in[t][y]--;
                if(in[t][y] == 0){
                    s.push(y);
                }
            }
        }
        if(cnt < 2*n) return 0;
//        for(int i = 1; i <= 2 * n; i++){
//            int index = path[t][i];
//            ans[t][index] = i-1;
//        }
//    }
    return 1;
}


int main(){
    int num = 0;
    while(cin >> n >> m){
        if(n == 0 && m == 0) break;
        num++;
        init();
        //xi1<xi2, yi1<yi2, zi1<zi2
        for(int j = 0; j < 3; j++){
            for(int i = 1; i <= n; i++){
                e[j][i].push_back(i+n);
                in[j][i+n]++;
            }
        }
        //
        for(int i = 1; i <= m; i++){
            cin >> ch >> a >> b;

            switch(ch){
                case 'I':   for(int j = 0; j < 3; j++){
                                e[j][a].push_back(b+n); in[j][b+n]++;
                                e[j][b].push_back(a+n); in[j][a+n]++;
                            }
                            break;
                case 'X':   e[0][a+n].push_back(b); in[0][b]++; break;
                case 'Y':   e[1][a+n].push_back(b); in[1][b]++; break;
                case 'Z':   e[2][a+n].push_back(b); in[2][b]++; break;
            }

        }
        if(topsort() == 1){
            cout << "Case " << num << ": POSSIBLE" << endl;
           for(int i = 1; i <= n; i++){
//                cout << ans[0][i] << " " << ans[1][i] << " " << ans[2][i] << " ";
//                cout << ans[0][i+n] << " " << ans[1][i+n] << " " << ans[2][i+n]<<endl;
                cout << path[0][i] << " " << path[1][i] << " " << path[2][i] << " ";
                cout << path[0][i+n] << " " << path[1][i+n] << " " << path[2][i+n]<<endl;
            }
        }
        else{
            cout << "Case " << num << ": IMPOSSIBLE" << endl;
        }
        cout << endl;
    }
}


对于答案的保存,刚开始用的是代码中斜杠//的部分,即从拓扑排序path [ ] 中再转化为ans[ ]:

  • path[t] [cnt++] = x;
  • ans[t] [ path[t] [i] ] = i-1;
  • cout << ans[t] [i] ;

但后面参考别人代码时发现了更优的做法,遂更改为:

  • path[t] [x] = cnt++;
  • cout << path[t] [i] ;
wa点

刚开始疯狂wa。。。原因是把第i个长方体某一维的坐标保存为2i-1, 2i了。后面改成i, i+n就过了…

更新:并不是!是因为写错字母了!IMPOSSIBLE→INPOSSIBLE,用2i-1, 2i也是可以的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值