Hdu3231 step5.2.7 Box Relations(拓扑排序)

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 876    Accepted Submission(s): 313

Special Judge

 

Problem Description

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

 

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

I i j: The intersection volume of Ci and Cjis positive.

 

X i j: The intersection volume is zero, andany point inside Ci has smaller x-coordinate than any point inside Cj.

 

Y i j: The intersection volume is zero, andany point inside Ci has smaller y-coordinate than any point inside Cj.

 

Z i j: The intersection volume is zero, andany point inside Ci has smaller z-coordinate than any point inside Cj.

.

 

 

Input

There will be at most 30 test cases. Eachcase 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 formatabove. The last test case is followed by n=R=0, which should not be processed.

 

 

Output

For each test case, print the case numberand either the word POSSIBLE or IMPOSSIBLE. If it's possible to construct theset of boxes, the i-th line of the following n lines 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. Theabsolute values of x1, y1, z1, x2, y2, z2 should not exceed 1,000,000.

 

Print a blank line after the output of eachtest 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 byWuhan University

 

题解:

这道题是一道很好的题,在3D的空间中,长方体i在每一维看成是两个点,如在x轴上,长方体i的两个点是i和i+n(i表示左边的点,i+n表示右边的点,还未知道在x轴上的位置)。这道题给出了偏序关系,这个关系是小于关系。

1.I,两个长方体x、y相交,在每个轴上都有x < y+n, y < x+n;

2.X,两个长方体在X轴上,长方体x的两个顶点都小于长方体的最左的顶点,即x+n < y;

3.Y,在y轴上有x+n

4.Z,在Z轴上有x+n

根据现有的偏序关系,用inx[],iny[],inz[]表示在特定轴上某个点的入度,即在现有条件下,某点比多少点大。而用vector vx[],vy[],vz[],记录在特定轴上某点的出度的值,即在现有条件下比哪些点小,根据上面的偏序条件记录后,进行拓扑排序,最后能将某轴上1到2*n个顶点拓扑完的,说明在该轴上,满足条件。

 

源代码:

#include

#include

#include

#include

#include

#define MAX 2050

 

using namespace std;

int inx[MAX],iny[MAX],inz[MAX];

vector<int> vx[MAX],vy[MAX],vz[MAX];

int ansx[MAX],ansy[MAX],ansz[MAX];

int n,m;

 

void init()

{

   memset(inx,0,sizeof(inx));

   memset(iny,0,sizeof(iny));

   memset(inz,0,sizeof(inz));

 

   for(int i = 1;i <= 2*n;i++)

   {

     vx[i].clear();

     vy[i].clear();

     vz[i].clear();

   }

 

   for(int i = 1;i <= n;i++)

   {

     vx[i].push_back(i+n);

     inx[i+n]++;

     vy[i].push_back(i+n);

     iny[i+n]++;

     vz[i].push_back(i+n);

     inz[i+n]++;

   }

}

 

bool topologicalsort(int*in,vector<int> v[],int *ans)

{

   intnum = 0;

   queue<int>q;

 

   for(int i = 1;i <= 2*n;i++)

   {

     if(!in[i])

        q.push(i);

   }

 

   while(!q.empty())

   {

     intx = q.front();

     q.pop();

     ans[x] = num++;

 

     for(int i = 0;i < v[x].size();i++)

     {

        intf = v[x][i];

        in[f]--;

        if(!in[f])

          q.push(f);

     }

   }

 

   if(num== 2*n)

     returntrue;

   else

     returnfalse;

}

int main()

{

   intcount = 0;

   charc[5];

   intx,y;

   while(scanf("%d%d",&n,&m) != EOF &&n + m)

   {

     init();

     for(int k = 0;k < m;k++)

     {

        scanf("%s%d%d",c,&x,&y);

        if(c[0]== 'I')

        {

          vx[x].push_back(y+n);

          inx[y+n]++;

          vx[y].push_back(x+n);

          inx[x+n]++;

 

          vy[x].push_back(y+n);

          iny[y+n]++;

          vy[y].push_back(x+n);

          iny[x+n]++;

 

          vz[x].push_back(y+n);

          inz[y+n]++;

          vz[y].push_back(x+n);

          inz[x+n]++;

        }

 

        elseif(c[0] == 'X')

        {

          vx[x+n].push_back(y);

          inx[y]++;

        }

        elseif(c[0] == 'Y')

        {

          vy[x+n].push_back(y);

          iny[y]++;

        }

        elseif(c[0] == 'Z')

        {

          vz[x+n].push_back(y);

          inz[y]++;

        }

     }

     intflag = 1;

     if(!topologicalsort(inx,vx,ansx)){flag = 0;}

     if(!topologicalsort(iny,vy,ansy)){flag = 0;}

     if(!topologicalsort(inz,vz,ansz)){flag = 0;}

 

     count++;

     if(flag)

     {

        cout << "Case " << count <<": POSSIBLE" <

        for(int i = 1;i <= n;i++)

          cout<< ansx[i]<<" " <" "  < " "

             << ansx[i+n]<<" "<" " << ansz[i+n] <

        cout << endl;

     }

     else

     {

       

        cout << "Case "<": IMPOSSIBLE"<

     }

    

   }

   return0;

}

 

你可能感兴趣的:(题解)