【hdu】3231 Box Relations【拓扑排序三维】

来源:互联网 发布:竞彩缩水软件 编辑:程序博客网 时间:2024/05/22 05:02

题意:空间中存在n个长方体,m个长方体之间的关系 I代表长方体相交 Xab代表a长方形的所有点x坐标小于b的任意一点 YZ同理 要求给出一组满足条件的坐标 否则输出-1

题解:一个长方体可以由一个体对角线上的两个端点表示也就是说2个三维坐标来表示 

我们可以对三维坐标分解来看 X代表a矩形的x轴坐标小于b矩阵的x轴坐标 

我们可以定义a的下表面为x1 上表面为x2 在x1x2建一条边表示x1小于x2 a的上表面与b的下表面建一条边代表X要求 YZ同理   

最复杂的就是I操作了 

之前我以为随便定义下就好 就直接把b写成包含在a里面了 WA了好多发 然后看了下别人blog才发现 

可以这样定义 A1<B2 B1<A2 

我们可以发现在这两个实质中A与B是可以互换的 所以无论怎么写都不会错 

然后这两个条件正好能包含所有可能的交叉情况 自己想还真是想不到 尴尬脸= = 

然后对三维各自进行拓扑排序就好

#include<cstdio>#include<cstring>using namespace std;const int N=1005;const int M=100100;bool inte[N][N];int A[N*6],in[N*6],NE,head[N*6],tmp[N*6],vis[N*6];struct node{    int v,next;}edge[M];void add(int u,int v){    in[v]++;    edge[NE].v=v;    edge[NE].next=head[u];    head[u]=NE++;}inline int x1(int a){return (a-1)*6;}inline int y1(int a){return (a-1)*6+1;}inline int z1(int a){return (a-1)*6+2;}inline int x2(int a){return (a-1)*6+3;}inline int y2(int a){return (a-1)*6+4;}inline int z2(int a){return (a-1)*6+5;}int topsort(int n,int id){    int level=0,cnt=0;    int i,now,k,t;    memset(vis,0,sizeof(vis));    while(1){        k=0;        for(i=0;i<n;i++){            now=i*6+id;            if(!vis[now]&&in[now]==0){                vis[now]=1;cnt++;                tmp[k++]=now;                A[now]=level;            }            now=i*6+3+id;            if(!vis[now]&&in[now]==0){                vis[now]=1;cnt++;                tmp[k++]=now;                A[now]=level;            }        }        if(cnt>=n*2)return 1;        if(!k) return 0;        for(i=0;i<k;i++){            t=tmp[i];            for(int j=head[t];j!=-1;j=edge[j].next)  in[edge[j].v]--;        }        level++;    }}int main(){//freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);    int kase=0,n,m,i,a,b;    char s[10];    while(scanf("%d%d",&n,&m)&&n+m){        NE=0;memset(inte,0,sizeof(inte));memset(head,-1,sizeof(head));memset(in,0,sizeof(in));        for(i=1;i<=n;i++)add(x1(i),x2(i)),add(y1(i),y2(i)),add(z1(i),z2(i));        while(m--){            scanf("%s%d%d",s,&a,&b);            if(s[0]=='I'&&!inte[a][b]){                inte[a][b]=inte[b][a]=1;                add(x1(a),x2(b));                add(x1(b),x2(a));                add(y1(a),y2(b));                add(y1(b),y2(a));                add(z1(a),z2(b));                add(z1(b),z2(a));            }            else if(s[0]=='X')  add(x2(a),x1(b));            else if(s[0]=='Y')  add(y2(a),y1(b));            else if(s[0]=='Z')  add(z2(a),z1(b));        }        if(topsort(n,0)&&topsort(n,1)&&topsort(n,2)){//对三维各自进行拓扑排序            printf("Case %d: POSSIBLE\n",++kase);            for(i=0;i<n;i++)printf("%d %d %d %d %d %d\n",A[i*6],A[i*6+1],A[i*6+2],A[i*6+3],A[i*6+4],A[i*6+5]);        }        else {printf("Case %d: IMPOSSIBLE\n",++kase);}        printf("\n");    }    return 0;}



0 0