hdu3231 拓扑序
2015-09-09 16:36
267 查看
题意:在空间内有多个长方体,有一系列关系,分别是 A 的所有点的 x 坐标都比 B 的所有点的 x 坐标小, A 的所有点的 y 坐标都比 B 的所有点的 y 坐标小, A 的所有点的 z 坐标都比 B 的所有点的 z 坐标小,或者是 A 和 B有体积相交。要求给出一个符合上述关系的各个长方体,输出它们主对角线上的两点坐标。
将每个长方体的 x 、 y 、 z 作为点。每个长方体有两个 x 点(x1为值小的点,x2为值大的点),两个 y 点,两个 z 点,他们之间的关系是用边表示, e(u,v) 表示 u 的值小于 v 的值,对于每个长方体的每一维的两点可以先建边,然后两长方体的坐标大小比较就是用坐标小的长方体的大值点(A 的 x2)向坐标大的长方体的小值点(B 的 x1)建边,而体积有相交则是两长方体的小值点向对方的大值点建边(A 的 x1 向 B 的 x2 ;B 的 x1 向 A 的 x2);然后对 x、y、z 分别求一遍拓扑序,再随意从小到大分配值就行了。
View Code
将每个长方体的 x 、 y 、 z 作为点。每个长方体有两个 x 点(x1为值小的点,x2为值大的点),两个 y 点,两个 z 点,他们之间的关系是用边表示, e(u,v) 表示 u 的值小于 v 的值,对于每个长方体的每一维的两点可以先建边,然后两长方体的坐标大小比较就是用坐标小的长方体的大值点(A 的 x2)向坐标大的长方体的小值点(B 的 x1)建边,而体积有相交则是两长方体的小值点向对方的大值点建边(A 的 x1 向 B 的 x2 ;B 的 x1 向 A 的 x2);然后对 x、y、z 分别求一遍拓扑序,再随意从小到大分配值就行了。
#include<stdio.h> #include<string.h> #include<queue> using namespace std; const int maxn=1005*2; const int maxm=110005; int id[3][maxn],n; int num[3][maxn]; int head[3][maxn],point[3][maxm],nxt[3][maxm],size[3]; char s[5]; void add(int a,int b,int c){ point[c][size[c]]=b; nxt[c][size[c]]=head[c][a]; head[c][a]=size[c]++; id[c][b]++; } bool topo(int c){ queue<int>q; for(int i=1;i<=2*n;++i)if(!id[c][i])q.push(i); int cnt=0; while(!q.empty()){ int u=q.front(); q.pop(); num[c][u]=++cnt; for(int i=head[c][u];~i;i=nxt[c][i]){ int j=point[c][i]; id[c][j]--; if(!id[c][j])q.push(j); } } if(cnt==2*n)return 1; return 0; } int main(){ int cnt=0,m; while(scanf("%d%d",&n,&m)!=EOF&&n+m){ memset(head,-1,sizeof(head)); memset(size,0,sizeof(size)); memset(id,0,sizeof(id)); for(int i=1;i<=n;++i){ add(2*i-1,2*i,0); add(2*i-1,2*i,1); add(2*i-1,2*i,2); } while(m--){ int a,b; scanf("%s%d%d",s,&a,&b); if(s[0]=='X')add(2*a,2*b-1,0); else if(s[0]=='Y')add(2*a,2*b-1,1); else if(s[0]=='Z')add(2*a,2*b-1,2); else if(s[0]=='I'){ add(2*a-1,2*b,0); add(2*a-1,2*b,1); add(2*a-1,2*b,2); add(2*b-1,2*a,0); add(2*b-1,2*a,1); add(2*b-1,2*a,2); } } printf("Case %d: ",++cnt); if(!topo(0))printf("IMPOSSIBLE\n"); else if(!topo(1))printf("IMPOSSIBLE\n"); else if(!topo(2))printf("IMPOSSIBLE\n"); else{ printf("POSSIBLE\n"); for(int i=1;i<=n;++i){ printf("%d %d %d %d %d %d\n",num[0][2*i-1],num[1][2*i-1],num[2][2*i-1],num[0][2*i],num[1][2*i],num[2][2*i]); } } printf("\n"); } return 0; }
View Code
相关文章推荐
- mysql性能测试(索引)
- Matlab 曲线拟合工具箱 cftool
- Winform 获取Win7 UAC 管理员权限
- 解决secureCRT登陆centOS显示中文乱码
- JavaScript移动端模拟alert()方法
- 译:Android Configuration(Android 配置)
- hdu 4324 Triangle LOVE(拓扑排序)
- iPhone自带click点击效果用css去除
- 从安全攻击实例看数据库安全(三)数据库攻击原理分析
- smarty模板中计算数组长度
- python2.7学习笔记(10) ——面向对象高级编程
- Zabbix禁止重装
- Swift2.0--文档学习笔记
- 巧用Comparator进行对象的属性合并
- UVa 658It's not a Bug, it's a Feature! -- 最短路dijkstra
- uva 1494 Qin Shi Huang's National Road System (次小生成树)
- 20150909
- zeppelin入门使用
- MyBatis接口的简单实现原理
- 没事的时候看看大神的博客(iOS界好的博客)