http://acm.hdu.edu.cn/showproblem.php?pid=3231
其实3维并不难处理,只是 , 如何 处理每一维 XYZ 上的 关系, 开始能想到用拓扑 就不好想, 如果没有 'I' 这个关系,可以把每个box在每一维上看做一个点,构造大小关系,但是有这个‘I',可以 把每个box的信息 分到每一维 上的两点,大小关系 a<a+n 代表一维上的两点,给出的relation x,y,z 都是对应的一维上的关系 eg : X 1 2 即 1+n<2
而 I 1 2 每一维上都是 1+n>2 && 1<w+n 之后根据大小关系拓扑排序,输出任意结果即可。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
using namespace std;
#define max(a,b) (a)>(b)? (a):(b)
#define min(a,b) (a)>(b)? (b):(a)
#define INT_MIN -0x7FFFFFFF
#define INF 100000000
#define N 1005
int n,r;
int in[5][2*N],dui[5][2*N];
vector<int> edge[5][2*N];
int ans[5][2*N];
void inser(int x,int y,int z)
{
int i,j,k;
in[x][z]++;
edge[x][y].push_back(z);
}
void init()
{
int i,j;
memset(in,0,sizeof(in));
for(i=1;i<=3;i++)
{
for(j=0;j<=2*n;j++)
{
edge[i][j].clear();
}
}
for(i=1;i<=3;i++)
{
for(j=1;j<=n;j++)
{
inser(i,j,j+n);
}
}
}
int topo(int x)
{
int i,j,k;
int head,tail;
head=tail=0;
for(i=1;i<=2*n;i++)
{
if(in[x][i]==0)
{
dui[x][tail++]=i;
}
}
while(head<tail)
{
int now=dui[x][head++];
for(i=0;i<edge[x][now].size();i++)
{
int next=edge[x][now][i];
in[x][next]--;
if(in[x][next]==0)
{
dui[x][tail++]=next;
}
}
}
return tail==2*n;
}
int main()
{
//freopen("in.txt","r",stdin);
int i,j,k;
int time=0;
while(scanf("%d%d",&n,&r)!=EOF &&(n||r) )
{
init();
char ch[5];
int a,b;
for(i=1;i<=r;i++)
{
scanf("%s%d%d",ch,&a,&b);
if(ch[0]=='I')
{
for(j=1;j<=3;j++)
{
inser(j,b,a+n);
inser(j,a,b+n);
}
}
else
{
inser(ch[0]-'X'+1,a+n,b);
}
}
int flag=0;
for(i=1;i<=3;i++)
{
int tem=topo(i);
if(!tem)
{
flag=1;
}
}
printf("Case %d: ",++time);
if(flag) printf("IMPOSSIBLE\n");
else
{
printf("POSSIBLE\n");
for(i=1;i<=3;i++)
{
for(j=0;j<2*n;j++)
{
ans[i][dui[i][j]]=j;
}
}
for(i=1;i<=n;i++)
{
printf("%d %d %d %d %d %d\n",ans[1][i],ans[2][i],ans[3][i],ans[1][i+n],ans[2][i+n],ans[3][i+n]);
}
}
puts("");
}
return 0;
}