1. 程式人生 > >HDU3231 Box Relations——三維拓撲刨銑

HDU3231 Box Relations——三維拓撲刨銑

這樣的 pac hdu ati bits turn blank push 上界

HDU3231 Box Relations

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3231

題目意思:在一個三維空間上有一些棱和坐標軸平行的立方體。給夠給予四種關系。I i j表示i,j兩個立方體是有部分的重合,X i j表示立方體i所有點x坐標都小於立方體j的x坐標,Y i j表示立方體i所有點y坐標都小於立方體j的y坐標,Z i j表示立方體i所有點Z坐標都小於立方體j的Z坐標。然後給出一系列這樣的關系,問你這些關系是否存在矛盾,如果不矛盾,對於每個立方體輸出六個參數x1,y1,z1,x2,y2,z2,分別代表x坐標的下界,y坐標的下界,z坐標的下界,x坐標的上界,y坐標的上界,z坐標的上界。

思路:在每個維度上分別拓撲排序。具體思路還沒有想的特別懂,大概明年了。還沒想好怎麽總結。這個坑以後再來補好了。

代碼 :

//Author: xiaowuga
#include <bits/stdc++.h>
#define maxx INT_MAX
#define minn INT_MIN
#define inf 0x3f3f3f3f
const long long N=2000+10;
using namespace std;
typedef long long LL;
vector<int>mapt[3][N];//3代表三個維度
int in[3][N],v[3][N],n;
void init(){ for(int i=0;i<3;i++) for(int j=1;j<=n*2;j++){ in[i][j]=v[i][j]=0; mapt[i][j].clear(); } for(int i=0;i<3;i++)//坐標x,y,z for(int j=1;j<=n;j++){//盒子j,用兩個點來表示,點j和j+n in[i][j+n]++; mapt[i][j].push_back(j
+n);//點j的坐標比相應的點j+n的坐標小 } } int topo(){ for(int i;i<3;i++){ int k=0; queue<int>q; for(int j=1;j<=n;j++){ if(in[i][j]==0){ q.push(j); k++;//對於入度為0的起點,作為拓撲起點 } } //拓撲套路 while(!q.empty()){ int s=q.front();q.pop(); for(int j=0;j<mapt[i][s].size();j++){ int t=mapt[i][s][j]; if(v[i][s]+1>v[i][t]) v[i][t]=v[i][s]+1;//t是s的後續所以s一定比t大是不合理的,所以我們需要更新t節點的坐標至少為s的坐標+1 if(--in[i][t]==0){ q.push(t);k++; } } } if(k!=n*2) return 0;//如果在其中一個維度不滿足關系則說明不滿足 } return 1; } int main() { ios::sync_with_stdio(false);cin.tie(0); char ch; int m,a,b,c=0; while(cin>>n>>m&&(n+m)){ init(); //我們添加的邊實際上是一種關系,我們把a當成第a個盒子的起點,a+n當成第a個盒子的終點 while(m--){ cin>>ch>>a>>b; //如果他們是相交的 if(ch==I){ for(int i=0;i<3;i++){ mapt[i][a].push_back(b+n);in[i][b+n]++;//a的起點小於b的終點 mapt[i][b].push_back(a+n);in[i][a+n]++;//b的起點小於a的終點 //說明a b是相交的 } } else if(ch==X) {mapt[0][a+n].push_back(b);in[0][b]++;}//在x軸上a的終點小於b的起點 else if(ch==Y) {mapt[1][a+n].push_back(b);in[1][b]++;}//在y軸上a的終點小於b的起點 else if(ch==Z) {mapt[2][a+n].push_back(b);in[2][b]++;}//在z軸上a的終點小於b的起點 } cout<<"Case "<<++c<<": "; if(!topo()) cout<<"IMPOSSIBLE"<<endl; else{ cout<<"POSSIBLE"<<endl; for(int i=1;i<=n;i++){ cout<<v[0][i]; for(int j=1;j<3;j++) cout<<" "<<v[j][i]; for(int j=0;j<3;j++) cout<<" "<<v[j][i+n]; cout<<endl; } } cout<<endl; } return 0; }

HDU3231 Box Relations——三維拓撲刨銑