[hdu 3231] Box Relations

[hdu 3231] Box Relations

Hdu 3231 Box Relations

题目描述:

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

    给定一些正方体的关系,要求一组符合这些关系的正方体坐标,如果不存在符合条件的正方体坐标,IMPOSSIBLE。(Special Judge)

 

题目分析:

    首先把正方体这个立体问题拆分成X,Y,Z三个维度上的的平面问题。三个维度上的平面问题处理完了,正方体问题也就处理完了。

    首先想到了差分约束系统,但是我的SPFA呃,TLE了……(求一个不TLE的差分约束系统标程……)

    上网搜索了一个大牛的文,说只需要拓补排序就可以了,完全不需要差分约束。

    再想一想,此题如果用差分约束系统来做,所有边权都是-1。其实不如更直观地进行构图,例如a<b,那么就构图map[a][b] = 1,也就是不妨看做a到b的边权为1。其实进行一下拓补排序,根据点的拓补排序的结果就可以直接作为答案输出,如果拓补排序失败也就是IMPOSSIBLE。

 

代码:

hdu3231
#include <cstdlib>
#include 
<cstdio>
#include 
<algorithm>
#define MAXN 2010
#define MAXR 500000
#define MAX 999999

typedef 
struct edges{
    
int v,w,next;
}
edge;

int N, R;
edge edge_X[MAXR], edge_Y[MAXR], edge_Z[MAXR];
int s_X[MAXN], s_Y[MAXN], s_Z[MAXN];
int index_X[MAXN], index_Y[MAXN], index_Z[MAXN];
int degree_X[MAXN], degree_Y[MAXN], degree_Z[MAXN];

void Add(struct edges e[], int start, int end, int index[], int degree[], int &tot){
    e[tot].v 
= end;
    e[tot].next 
= index[start];
    index[start] 
= tot++;
    degree[end]
++;
}


bool init(){
    
int i, totx, toty, totz; 
    scanf(
"%d%d"&N, &R);
    
if (N == 0 && R == 0return false;
    memset(index_X, 
255sizeof(*index_X)*MAXN); //-1 indicates end of link
    memset(index_Y, 255sizeof(*index_Y)*MAXN); 
    memset(index_Z, 
255sizeof(*index_Z)*MAXN); 
    memset(degree_X, 
0sizeof(*degree_X)*MAXN);
    memset(degree_Y, 
0sizeof(*degree_Y)*MAXN);
    memset(degree_Z, 
0sizeof(*degree_Z)*MAXN);
    totx 
= toty = totz = 0;
    
    
for (i=1; i<=N; i++){
        
// node 0是超级汇点,最大的点。值为0
        Add(edge_X, 0, i, index_X, degree_X, totx);         //x1 of n-th Cube
        Add(edge_Y, 0, i, index_Y, degree_Y, toty);
        Add(edge_Z, 
0, i, index_Z, degree_Z, totz);
        Add(edge_X, i, i
+N, index_X, degree_X, totx);
        Add(edge_Y, i, i
+N, index_Y, degree_Y, toty);
        Add(edge_Z, i, i
+N, index_Z, degree_Z, totz);
    }

    
for (i=1; i<=R; i++){
        
char t[10];
        
int  A, B;
        scanf(
"%s%d%d", t, &A, &B);
        
if (t[0== 'I'){
            Add(edge_X, A, B
+N, index_X, degree_X, totx);        //x1(A) < x1(B)
            Add(edge_X, B, A+N, index_X, degree_X, totx);        //x2(A) > x1(B) or x1(B) < x2(A)
            Add(edge_Y, A, B+N, index_Y, degree_Y, toty);
            Add(edge_Y, B, A
+N, index_Y, degree_Y, toty);
            Add(edge_Z, A, B
+N, index_Z, degree_Z, totz);
            Add(edge_Z, B, A
+N, index_Z, degree_Z, totz);
        }

        
if (t[0== 'X')
            Add(edge_X, A
+N, B, index_X, degree_X, totx);    //x2(A) < x1(B)
        if (t[0== 'Y')
            Add(edge_Y, A
+N, B, index_Y, degree_Y, toty);    //y2(A) < y1(B)
        if (t[0== 'Z')
            Add(edge_Z, A
+N, B, index_Z, degree_Z, totz);    //z2(A) < z1(B)    
    }

    
return true;
}


bool NonPreFirstTopSort(edge e[], int index[], int degree[], int n, int s[]){
    
int i, count(0), head(0), tail(1);
    
int Q[MAXN];
    
    Q[
0= 0;
    
    
while (head != tail){
        s[Q[head]] 
= count++;
        i 
= index[Q[head]];
        
while (i != -1){
            
if (--degree[e[i].v] == 0) Q[tail++= e[i].v;
            i 
= e[i].next;
        }

        
++head;
    }

    
    
if (count < n) return false;
    
else return true;
}


int main(){
    
int Cases = 0, i;
    
while (init() && ++Cases){
        
bool flag;
        flag 
= NonPreFirstTopSort(edge_X, index_X, degree_X, N*2 + 1, s_X);
        
if (flag) flag = NonPreFirstTopSort(edge_Y, index_Y, degree_Y, N*2 + 1, s_Y);
        
if (flag) flag = NonPreFirstTopSort(edge_Z, index_Z, degree_Z, N*2 + 1, s_Z);
        
if (flag){
            printf(
"Case %d: POSSIBLE\n", Cases);
            
for (i=1; i<=N; i++)
                printf(
"%d %d %d %d %d %d\n", s_X[i], s_Y[i], s_Z[i], s_X[i+N],  s_Y[i+N], s_Z[i+N]);
            printf(
"\n");
            
        }

        
else
            printf(
"Case %d: IMPOSSIBLE\n\n", Cases);
    }

    
//system("pause");
    return 0;
}


    
        
    

你可能感兴趣的:([hdu 3231] Box Relations)