Box Relations
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1108 Accepted Submission(s): 420
Special Judge
There are four kinds of relations (1 <= i,j <= n, i is different from j):
- I i j: The intersection volume of Ci and Cj is positive.
- X i j: The intersection volume is zero, and any point inside Ci has smaller x-coordinate than any point inside Cj.
- Y i j: The intersection volume is zero, and any point inside Ci has smaller y-coordinate than any point inside Cj.
- Z i j: The intersection volume is zero, and any point inside Ci has smaller z-coordinate than any point inside Cj.
Print a blank line after the output of each test case.
題意:三維座標下讓你構造滿足條件的n個長方體。有R個要求,I i j表示第i個長方體和第j個長方體必須有交集; X i j 表示 i 任意一點的x座標必須小於 j 的;
Y i j ,Z i j同理。
題解 拓撲排序。分別把三個面拆成三條線段,再拆成兩個點,根據要求構造關係,再進行三次拓撲排序即可。
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<queue>
#include<set>
using namespace std;
const int N=2005;
const int M=2e5+5;
int n,m;
int c[N];
int topo[N],t;
vector<int>X[N],Y[N],Z[N];
int ans[3][N];
void init() {
for(int i=0; i<=2*n; i++) {
X[i].clear();
Y[i].clear();
Z[i].clear();
}
for(int i=0; i<n; i++) {
X[i].push_back(i+n);
Y[i].push_back(i+n);
Z[i].push_back(i+n);
}
}
bool dfs(int u,vector<int>G[]) {
c[u]=-1;
for(int v=0; v<G[u].size(); v++) {
int to=G[u][v];
if(c[to]<0)return false;
else if(!c[to]&&!dfs(to,G))return false;
}
c[u]=1;
topo[--t]=u;
return true;
}
bool toposort(vector<int>G[]) {
t=2*n;
memset(c,0,sizeof (c));
for(int u=0; u<2*n; u++) {
if(!c[u])if(!dfs(u,G))return false;
}
return true;
}
bool solve() {
if(!toposort(X))return false;
for(int i=0; i<2*n; i++)
ans[0][topo[i]]=i;
if(!toposort(Y))return false;
for(int i=0; i<2*n; i++)
ans[1][topo[i]]=i;
if(!toposort(Z))return false;
for(int i=0; i<2*n; i++)
ans[2][topo[i]]=i;
return true;
}
int main() {
// freopen("test.in","r",stdin);
int ca=1;
while(~scanf("%d%d",&n,&m)&&(n+m)) {
char c[2];
int x,y;
init();
while(m--) {
scanf("%s%d%d",c,&x,&y);
x--,y--;
if(c[0]=='I') {
X[x].push_back(y+n);
X[y].push_back(x+n);
Y[x].push_back(y+n);
Y[y].push_back(x+n);
Z[x].push_back(y+n);
Z[y].push_back(x+n);
} else if(c[0]=='X') {
X[x+n].push_back(y);
} else if(c[0]=='Y') {
Y[n+x].push_back(y);
} else {
Z[n+x].push_back(y);
}
}
if(!solve()) {
printf("Case %d: IMPOSSIBLE\n\n",ca++);
continue;
}
printf("Case %d: POSSIBLE\n",ca++);
for(int i=0; i<n; i++) {
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]);
}
putchar(10);
}
return 0;
}