发现n维超立方体有2^n个定点,2^(n-1)*n条棱,每个点的度数为n
发现只有在二进制表示下 只有一位不同的两个点之间才有边
于是check上面那三个点可以先判断-1
用id[i] 表示 i 号点的标号
然后进行标号把原来的0号点标为0,与它相邻的点分别标为2,4,8,16....
从与0号点相邻的点开始bfs,每个点记录dis[i],表示i号点与0号点的距离+1(为了方便 dis[0] = 1)
对于与 i 相邻的点 j ,如果dis[j] == dis[i] + 1 ,id[j] |= id[i]
最后check每个边两边的点是否合法,是否有重复的标号
#include<bits/stdc++.h>
#define MAXN 32800
#define MAXM 1000005
using namespace std; int Q,n,m;
int Base,tmp_base;
inline int read(){
register char ch = getchar();
while(!isdigit(ch)) ch = getchar();
register int rtn = 0;
while(isdigit(ch)) rtn = rtn*10 + ch - '0' , ch = getchar();
return rtn;
}
//=======================================
struct t1{
int to,nxt;
}edge[MAXM<<1]; int cnt_edge;
int dex[MAXN];
int fst[MAXN];
inline void addedge(int x,int y){
++dex[x] , ++dex[y];
edge[++cnt_edge].to = y;
edge[cnt_edge].nxt = fst[x];
fst[x] = cnt_edge;
edge[++cnt_edge].to = x;
edge[cnt_edge].nxt = fst[y];
fst[y] = cnt_edge;
}
int id[MAXN];
int dis[MAXN];
queue<int> q;
inline void bfs(){
while(!q.empty()){
int now = q.front();
q.pop();
for(int tmp = fst[now];tmp;tmp=edge[tmp].nxt){
int aim = edge[tmp].to;
if(!dis[aim]){
dis[aim] = dis[now] + 1;
q.push(aim);
id[aim] = id[now];
}else{
if(dis[aim] == dis[now] + 1)
id[aim] |= id[now];
}
}
}
}
int vis[MAXN];
inline void check(){
// __builtin_popcount()
memset(vis,0,sizeof vis);
for(int i=0;i<n;++i){
if(vis[id[i]]) return void(puts("-1"));
vis[id[i]] = 1;
for(int tmp = fst[i];tmp;tmp=edge[tmp].nxt){
if(__builtin_popcount(id[i]^id[edge[tmp].to]) ^ 1)
return void(puts("-1"));
}
}
for(int i=0;i<n;++i) printf("%d ",id[i]);
puts("");
}
int main(){
// freopen("1.in","r",stdin);
Q = read();
while(Q--){
memset(fst,0,sizeof fst);
memset(edge,0,sizeof edge);
memset(id,0,sizeof id);
memset(dex,0,sizeof dex);
memset(dis,0,sizeof dis);
cnt_edge = 0;
n = read() , m = read();
for(Base = 0 , tmp_base = 1;tmp_base<n;++Base , tmp_base<<=1);
for(int i=1;i<=m;++i) addedge(read(),read());
if((tmp_base^n)||(m^((n/2)*Base))){
puts("-1");
continue;
}
int flag = 0;
for(int i=0;i<n;++i) if(dex[i]^(Base)){
puts("-1");
flag = 1;
break;
}
if(flag) continue;
id[0] = 0;
dis[0] = 1;
for(int tmp = fst[0],i = 1;tmp;tmp = edge[tmp].nxt , i<<=1)
id[edge[tmp].to] = i , q.push(edge[tmp].to) , dis[edge[tmp].to] = 2;
bfs();
check();
}
return 0;
}