码迷,mamicode.com
首页 > 其他好文 > 详细

太鼓达人:欧拉回路(暴搜)

时间:2019-07-12 12:41:08      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:strong   ++   路径   char   二分   基于   oid   pat   putchar   

技术图片

一上来这个专题就死磕了这道题一上午,然后发现

类似二分图?2h 样例都过不去

类似状压?1h 过样例了,WA 0

类似暴搜?10min AC

然而正解是欧拉回路

欧拉回路:

如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。具有欧拉回路的图称为欧拉图

判断条件:

以下判断基于此图的基图连通。
无向图存在欧拉回路的充要条件
一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图。
有向图存在欧拉回路的充要条件
一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图。

前k个一定是0,确定好初态后,每次转移只会出现两种情况:0或1

因此dfs即可

注意在末态判断是要和初态完美契合

Code

技术图片
#include<cstdio>
#include<vector>
int ak,k,a[5000],ans[5000],num,rnum,full[15],pow[15],q[5000];
void bfs(int la,int tot){
    if(ak)return;
    if(tot==pow[k]){
        if(ak)return;
        bool ok=1;
        //for(int i=1;i<=num;++i)printf("%d",ans[i]);puts("");
        for(int i=1;i<=k-1;++i){
            int up=((la<<i)&full[k]);
            if(a[up]){ok=0;break;}
            else q[++q[0]]=up,a[up]=1;
        }
        for(int i=1;i<=q[0];++i)a[q[i]]=0;q[0]=0;
        if(!ok)return;
        while(num)if(!ans[num])num--,rnum++;else break;
        for(int i=1;i<=rnum;++i)putchar(0);
        for(int i=1;i<=num;++i)printf("%d",ans[i]);puts("");
        ak=1;
    }
    la<<=1;
    if(!a[la]){
        a[la]=1;
        ans[++num]=0;
        bfs(la&full[k-1],tot+1);
        a[la]=0;
        --num;
    }
    if(!a[la|1]){
        a[la|1]=1;
        ans[++num]=1;
        bfs((la|1)&full[k-1],tot+1);
        a[la|1]=0;
        --num;
    }
}
int main(){
    scanf("%d",&k);
    for(int i=0;i<=k;++i)full[i]=(1<<i)-1;
    for(int i=0;i<=k;++i)pow[i]=(1<<i);
    rnum=k;
    printf("%d ",pow[k]);
    a[0]=1;bfs(0,k);
    return 0;
}

 

太鼓达人:欧拉回路(暴搜)

标签:strong   ++   路径   char   二分   基于   oid   pat   putchar   

原文地址:https://www.cnblogs.com/hzoi2018-xuefeng/p/11175341.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!