[bfs+位运算] 牛客周周练15C璀璨光滑

题目

在这里插入图片描述

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/kosf_/article/details/107367680