题目
题目链接:https://ac.nowcoder.com/acm/contest/6290/C
思路
由题目,二进制位上差1的点都相连,所以每个n对应的图都是固定的,并且每一层增加一个1。1号点一定是数字0,与它最短路为x的点有x个1。然后从0开始bfs,先随便分配一个解。把解求出来之后,可以按位进行排序,排出最小解
代码
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
int val[300010];
vector<int> v[300010];
bool vis[300010],vis2[300010];
struct sut{
bool num[300010];
}s[20];
int n,m;
bool cmp(sut a,sut b)
{
for(int i=1;i<=(1<<n);i++)
if(a.num[i]!=b.num[i])
return a.num[i]>b.num[i];
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=(1<<n);i++){
val[i]=0;
v[i].clear();
vis[i]=0;
vis2[i]=0;
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
v[x].push_back(y);
v[y].push_back(x);
}
val[1]=0;vis2[1]=vis[1]=1;
queue<int> q;
for(int i=0;i<v[1].size();i++){
val[v[1][i]]=(1<<i);
q.push(v[1][i]);
vis2[v[1][i]]=1;
}
while(!q.empty()){//bfs
int x=q.front();
q.pop();
vis[x]=1;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(vis[y]) continue;
val[y]|=val[x];
if(!vis2[y]){q.push(y);vis2[y]=1;}
}
}
for(int i=1;i<=(1<<n);i++){
for(int j=0;j<n;j++){
s[j].num[i]=(val[i]>>j)&1;
}
}
sort(s,s+n,cmp);//按位排序
int res=0;
for(int i=1;i<=(1<<n);i++){
res=0;
for(int j=0;j<n;j++){
if(s[j].num[i]) res|=(1<<j);
}
cout<<res<<" ";
}
cout<<endl;
}
return 0;
}