题目链接:http://acm.uestc.edu.cn/#/problem/show/1642
欧拉回路
考虑用一条边表示一个数,那么题目要求就是无重复的遍历完所有边,
则这是一个欧拉图的问题。
建图:
对于有公共点的两条边,第一个的后n-1位和第二个的前n-1相同。
这样将一条边的前n-1位和后n-1位作为点,连边,这样来表示它。
如:对于01101,我们可以从0110向1101建一条有向边表示01101.
于是所建图有2^(n-1)个点,和2^n条边。
对于任一两个点,如果它们的前n-2位和后n-2位相同,就连一条有向边,
这样所得到的图一定是欧拉图,因为每个点的入度和出度都是2,一定存在
欧拉回路。
#include <bits/stdc++.h>
using namespace std;
const int maxn = (1<<15)+7;
//2^(n-1)个点,2^n条边
vector <pair<int, int> > G[maxn];
bool vis[maxn];
vector <int> way;
int n;
void dfs(int u)
{
int v, e;
if(!G[u].empty()){
v = G[u].back().second, e = G[u].back().first;
G[u].pop_back();
if(!vis[e]){
vis[e] = 1;
dfs(v);
way.push_back(e);
}
}
}
int main()
{
scanf("%d", &n);
for(int i = 0; i < (1<<n); i++){
int u = i>>1;
int v = i % (1<<(n-1));
G[u].push_back(make_pair(i,v));
}
memset(vis,0,sizeof(vis));
dfs(0);
way.clear();
for(int i=0; i<(1<<n); i++){
putchar(char('0'+(way[i]&1)));
}
putchar('\n');
return 0;
}