题目链接: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(""); } }
HDU 3213 Box Relations(拓扑排序构造),布布扣,bubuko.com
HDU 3213 Box Relations(拓扑排序构造)
原文地址:http://www.cnblogs.com/jianglangcaijin/p/3799700.html