我们发现0这个位置肯定是0
剩下来的n个位置如果确定了,那么整个序列就可以确定了
那么这些位置决定的根据是什么呢,当然是最后输出的字典序了
所以我们先随便赋值,sort时直接改一下cmp就可以得出最后的答案了
比较时如果相同那么交不交换都对它的位置没有影响,否则交换后对应位置的数就会改变
把dp[i]位置的1改到i位置再输出就可以了
#include<bits/stdc++.h>
using namespace std;
int maxa,m,shu1,shu2,trans[4000005];
vector <int> vec[4000005];
int n,vis[4000005],dp[25],instk[4000005];
queue<int> que;
int read()
{
char c;int x;
for(c=getchar();c!='-'&&(c>'9'||c<'0');c=getchar());
if(c=='-')
{
x=0;
for(c=getchar();c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
return -x;
}
else
{
x=c-'0';
for(c=getchar();c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
return x;
}
}
bool cmp(const int &x,const int &y)
{
for(int i=0;i<=maxa;i++)
{
if((trans[i]>>x&1)&&!(trans[i]>>y&1)) return true;
if(!(trans[i]>>x&1)&&(trans[i]>>y&1)) return false;
}
}
int main()
{
cin>>n;m=n*(1<<(n-1));maxa=(1<<n)-1;
for(int i=1;i<=m;i++)
{
shu1=read();shu2=read();
vec[shu1].push_back(shu2),vec[shu2].push_back(shu1);
}
vis[0]=1;
int cnt=0;
for(vector <int> :: iterator it=vec[0].begin(),ed=vec[0].end();it!=ed;it++)
{
int y=*it;
que.push(y);
trans[y]=1<<cnt;
cnt++;
vis[y]=1;
}
while(!que.empty())
{
int x=que.front();
vis[x]=1;
que.pop();
for(vector <int> :: iterator it=vec[x].begin(),ed=vec[x].end();it!=ed;it++)
{
int y=*it;
if(vis[y]) continue;
trans[y]|=trans[x];
if(!instk[y])
que.push(y);
instk[y]=1;
}
}
for(int i=0;i<n;i++) dp[i]=i;
sort(dp,dp+n,cmp);
for(int i=0;i<=maxa;i++)
{
int now=0;
for(int j=0;j<n;j++)
if(trans[i]>>dp[j]&1) now|=1<<j;
trans[i]=now;
}
for(int i=0;i<=maxa;i++)
printf("%d ",trans[i]);
return 0;
}
/*
2
0 2
0 3
2 1
3 1
*/