题意:
给定三位空间的两个矩形,满足三种关系,
- I a,b 表示矩形a跟b想交
- X a,b 表示矩形a的x坐标恒小于b的x坐标
- Y a,b 表示矩形a的y坐标恒小于b的y坐标
- X a,b 表示矩形a的z坐标恒小于b的z坐标
分析:
很明显就是一个拓扑排序,但是难点是三维如何去处理,可以将每个矩形的与同一坐标垂直的两个面进行初始化,前面的指向后面
的。用面进行拓扑排序。然后如果想交,得格外注意一下,如果设前一个矩形的两个面为a,a+n,后一个矩形的面为b,b+n,那么
a->b+n b->a+n 即可表示两个矩形肯定相交(这块不好想到)。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e3+10;
int val[3][maxn];
int in[3][maxn];
vector<int> g[3][maxn];
int n,m;
void init(){
memset(val,0,sizeof val);
memset(in,0,sizeof in);
for(int i=0;i<3;i++){
for(int j=0;j<maxn;j++){
g[i][j].clear();
}
}
for(int i=0;i<3;i++){
for(int j=1;j<=n;j++){
in[i][j+n]++;
g[i][j].push_back(j+n);
}
}
}
bool topo(){
for(int i=0;i<3;i++){
int cnt=0;
queue<int>q;
for(int j=1;j<=n;j++){
if(!in[i][j]){
q.push(j);
val[i][j]=cnt++;
}
}
while(!q.empty()){
int a=q.front();q.pop();
for(int j=0;j<g[i][a].size();j++){
int b=g[i][a][j];
val[i][b]=max(val[i][b],val[i][a]+1);
if(--in[i][b]==0){
q.push(b);
cnt++;
}
}
}
if(cnt!=n*2) return 0;
}
return 1;
}
int main(){
int cs=1;
while(~scanf("%d%d",&n,&m)&&n+m){
init();
while(m--){
char ch;
int a,b;
scanf(" %c%d%d",&ch,&a,&b);
if(ch=='I'){
for(int i=0;i<3;i++){
in[i][a+n]++;g[i][b].push_back(a+n);
in[i][b+n]++;g[i][a].push_back(b+n);
}
}else if(ch=='X'){
in[0][b]++;g[0][a+n].push_back(b);
}else if(ch=='Y'){
in[1][b]++;g[1][a+n].push_back(b);
}else{
in[2][b]++;g[2][a+n].push_back(b);
}
}
printf("Case %d: ",cs++);
if(topo()){
printf("POSSIBLE\n");
for(int i=1;i<=n;i++){
printf("%d %d %d %d %d %d\n",val[0][i],val[1][i],val[2][i],val[0][i+n],val[1][i+n],val[2][i+n]);
}
}else{
printf("IMPOSSIBLE\n");
}
printf("\n");
}
return 0;
}