bzoj 4466 : [Jsoi2013]超立方体
2016-05-23 16:38
615 查看
这题有毒
首先,我们发现如果一张图合法,那么点数为2n2^{n},边为2n−1∗n2^{n-1}*n
每个点度数为nn,并且图中没有奇数长度的环
我们可以假设00号点的新编号为00,并且把00点相连的边编号赋成1,2,4,8,16……1,2,4,8,16……
然后bfs一遍,确定每个点编号
怎么bfs呢?我们注意到,两个点有边当且仅当两个点新编号二进制位差11
假设a−ba-b有边且a−ca-c有边,且b,cb,c到00号点距为x,aa到00号点距为x+1x+1,那么aa点编号=b=b点编号 oror cc点编号
最后判一下每条边是否合法,编号是不是1到n1到n就行了
首先,我们发现如果一张图合法,那么点数为2n2^{n},边为2n−1∗n2^{n-1}*n
每个点度数为nn,并且图中没有奇数长度的环
我们可以假设00号点的新编号为00,并且把00点相连的边编号赋成1,2,4,8,16……1,2,4,8,16……
然后bfs一遍,确定每个点编号
怎么bfs呢?我们注意到,两个点有边当且仅当两个点新编号二进制位差11
假设a−ba-b有边且a−ca-c有边,且b,cb,c到00号点距为x,aa到00号点距为x+1x+1,那么aa点编号=b=b点编号 oror cc点编号
最后判一下每条边是否合法,编号是不是1到n1到n就行了
#include<bits/stdc++.h> #define ms(a) memset(a,0,sizeof a) using namespace std; inline void splay(int &v){ v=0;char c=0;int p=1; while(c<'0' || c>'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p; } #define N 32769 #define M 2000010 int nxt[M],fir ,sz,to[M],vis ,n,m,dl ,val ,dis ,p ,du ; void add(int x,int y){ nxt[++sz]=fir[x];fir[x]=sz;to[sz]=y;du[x]++; } bool is(int x){ if(x==0)return 0; return x==(x&-x); } int main(){ int q;for(splay(q);q;q--){ splay(n),splay(m); sz=0;bool fl=1; ms(fir),ms(du),ms(vis),ms(dis),ms(val); for(int i=1;i<=m;i++){ int x,y;splay(x),splay(y); add(x,y),add(y,x); } if(n==1){puts(m?"-1":"0");continue;} int bit=0; for(int i=0;i<=20;i++){ if((1<<i)==n)bit=i; } if(!bit){puts("-1");continue;} if((1<<(bit-1))*bit!=m){puts("-1");continue;} for(int i=0;i<n;i++)if(du[i]!=bit)fl=0; if(!fl){puts("-1");continue;} int head=0,tail=0,tot=-1;vis[0]=1; for(int u=fir[0];u;u=nxt[u]){ dl[++tail]=to[u];dis[to[u]]=1; val[to[u]]=1<<(++tot); vis[to[u]]=1; } while(head!=tail){ int v=dl[++head]; for(int u=fir[v];u;u=nxt[u]){ if(!vis[to[u]]){ vis[to[u]]=1;dis[to[u]]=dis[v]+1; dl[++tail]=to[u]; } if(dis[to[u]]==dis[v]+1)val[to[u]]|=val[v]; } } for(int i=0;i<n;i++){ for(int u=fir[i];u;u=nxt[u]){ if(!is(val[i]^val[to[u]])){ fl=0; } } } for(int i=0;i<n;i++)p[i]=val[i]; sort(p,p+n); for(int i=0;i<n;i++)if(p[i]!=i)fl=0; if(!fl){puts("-1");continue;} else{ for(int i=0;i<n;i++){ printf("%d ",val[i]); } printf("\n"); } } }
相关文章推荐
- 使用bookshelf.js进行left join操作
- JSP
- javascript类学习(二)——类的私有变量、私有方法、共有变量、共有方法
- 关于Chrome调试中.min.js.map 404的问题
- JSON.stringify()、,JSON.eval(),JSON.parse()各自的区别于作用
- js提示确认删除吗
- Javascript的this用法
- js获取url参数,操作url参数
- 使用JavaScript进行进制转换将字符串转换为十进制
- javascript类学习(一)——构造器与原型链实现简单的继承
- json解析总结
- js 自定义弹出框
- JS实现字体逐个显示
- 从服务器下载&&OTA升级&&JSON文件解析
- JSP空指针异常问题
- JSP之——表单信息和图片一起提交
- 安卓中解析json数据问题积累
- Javascript实现页面加载完成后自动刷新一遍清除缓存文件
- 原生js的数组除重复
- ExtJS textField 关于验证(Regex)的一些属性说明