题目链接: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,那么首先有边<i,i+n>,即同一个长方体的左下角的点的x坐标必然小于其右上角的x坐标。对于相 交的x和y有<x,y+n> <y,x+n>,对于不相交的有<x+n,y>。然后就是判断是不是拓扑图就行了。是的话依次按照0,1,2开始标号。
vector<int> g[3][N];
int d[3][N],ans[3][N],n,m;
void Add(int i,int u,int v)
{
g[i][u].pb(v);
d[i][v]++;
}
void build()
{
int i,j,x,y;
FOR0(i,3) FOR0(j,N) g[i][j].clear(),d[i][j]=0;
char op[5];
FOR0(i,3) FOR1(j,n) Add(i,j,j+n);
while(m--)
{
RD(op); RD(x,y);
if(op[0]=='I')
{
FOR0(i,3) Add(i,x,y+n),Add(i,y,x+n);
}
else Add(op[0]-'X',x+n,y);
}
}
int top_sort(int t)
{
int cnt=0;
queue<int> Q;
int i,j,u;
FOR1(i,n+n) if(!d[t][i]) ans[t][i]=cnt++,Q.push(i);
while(!Q.empty())
{
j=Q.front();
Q.pop();
FOR0(i,SZ(g[t][j]))
{
u=g[t][j][i];
if(--d[t][u]==0) Q.push(u),ans[t][u]=cnt++;
}
}
return cnt==n+n;
}
void deal()
{
int i;
FOR0(i,3) if(!top_sort(i))
{
puts("IMPOSSIBLE");
return;
}
puts("POSSIBLE");
FOR1(i,n) 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]);
}
int main()
{
int num=0;
Rush(n)
{
RD(m);
if(!n&&!m) break;
build();
printf("Case %d: ",++num);
deal(); puts("");
}
}