bzoj 3033 太鼓达人——欧拉图搜索
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3033
思路:肯定是把2^m个数当成点,每个点连了2条入边、2条出边,然后求一个经过所有点一次的路径。
但是这怎么做?又不是欧拉路的定义。
肯定是把点变成边,于是一条边会连4条边,就用点把它们粘起来就能求个欧拉路了。
然后觉得这不是个欧拉图吧? >o-o< 了以后,把右边的两条边转一转连一连,好像得出每个点连5条边的结论?(3条边)
怎么办?TJ:https://blog.csdn.net/Clove_unique/article/details/70160122
原来是这样啊。分析一下点和边的含义,以点为中心分析它的度数。得出:这就是个欧拉图。
然后怎么求欧拉路?
竟然是暴搜。
有一些细节。比如dfs什么时候到终点之类的。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=(1<<10)+5,M=(1<<11)+5; int m,lm,mod; bool vis[M],flag,ans[M]; void dfs(int nw,int k)//在第k位 { if(k==m+lm){flag=1;return;} if(k<=lm) for(int i=0;i<=1;i++) { int s=((nw<<1)|i); if(vis[s])continue; ans[k]=i; vis[s]=1; dfs(s&mod,k+1); if(flag)return; vis[s]=0; } else{ int s=((nw<<1)|ans[k-lm]); if(vis[s])return;vis[s]=1; dfs(s&mod,k+1); if(flag)return; vis[s]=0; } } int main() { scanf("%d",&m);mod=(1<<(m-1));lm=(mod<<1);mod--; printf("%d ",lm); for(int s=0;s<lm;s++) { dfs(s,m);if(flag)break; } for(int i=1;i<=lm;i++)printf("%d",ans[i]); return 0; }