三维拓扑排序好题hdu3231

时间:2023-03-09 16:45:17
三维拓扑排序好题hdu3231
/*
三维拓扑排序
将每个长方体分解成六个面,xyz三维进行操作
每一维上的的所有长方体的面都应该服从拓扑关系,即能够完成拓扑排序
=如果两个长方体的关系时相交,那么其对应的三对面只要交叉即可 如 a1 b1 a2 b2
反之对应的那对面不可以交叉 如a1 a2 b1 b2
同时长方体自身的对应两个面也具有拓扑关系
*/
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
struct Edge{int to,nxt;}edge[][maxn*];
int head[][maxn],tot[],in[][maxn],pos[][maxn];
int n,m;
void init(){
memset(head,-,sizeof head);
tot[]=tot[]=tot[]=;
}
void addedge(int k,int u,int v){
edge[k][tot[k]].to=v;
edge[k][tot[k]].nxt=head[k][u];
head[k][u]=tot[k]++;
} int solve(int k){//对第k维上的面进行拓扑排序
int cnt=;
queue<int>q;
for(int i=;i<=n*;i++)
if(in[k][i]==)
q.push(i);
while(!q.empty()){
int u=q.front();
q.pop();
cnt++;
for(int i=head[k][u];i!=-;i=edge[k][i].nxt){
int v=edge[k][i].to;
in[k][v]--;
if(in[k][v]==){
q.push(v);
pos[k][v]=pos[k][u]+;
}
}
}
if(cnt==*n)return ;
else return ;
} int main(){
int tt=;
while(cin>>n>>m && n){
init();
memset(in,,sizeof in);
memset(pos,,sizeof pos); for(int i=;i<;i++)//每个长方体自身的约数
for(int j=;j<=n;j++){
in[i][j+n]++;
addedge(i,j,j+n);
} while(m--){
char ch;
int u,v;
cin>>ch>>u>>v;
if(ch=='I'){
for(int i=;i<;i++){
in[i][u+n]++;
addedge(i,v,u+n);
in[i][v+n]++;
addedge(i,u,v+n);
}
}
else {
in[ch-'X'][v]++;
addedge(ch-'X',u+n,v);
}
} int ans0=solve();
int ans1=solve();
int ans2=solve();
if(ans1== || ans2== || ans0==){
printf("Case %d: IMPOSSIBLE\n\n",++tt);
continue;
}
printf("Case %d: POSSIBLE\n",++tt);
for(int i=;i<=n;i++){
printf("%d %d %d ",pos[][i],pos[][i],pos[][i]);
printf("%d %d %d\n",pos[][i+n],pos[][i+n],pos[][i+n]);
}
puts("");
}
}