zoukankan      html  css  js  c++  java
  • 欧拉回路

    定义:从无向图中一个节点出发,每条边走且仅走一次。(一笔画)

    条件:图为连通并且度数为奇数的点不超过两个。

    对于有向图则为出度不等于入度的点不超过两个。

    题目要求多为判断是否是欧拉图以及输出路径

    入门题目hdu1878:http://acm.hdu.edu.cn/showproblem.php?pid=1878

    检验题目所给的图是不是欧拉图,记录度数并且检验图联通性即可。

    ps:题目要求度数全部为偶数真是不懂

    #include<cstdio>
    #include<cstring>
    const int N=1005;
    struct X
    {
        int v,f,n;
    }x[1000005];
    int s,to[N];
    bool vis[N];
    void add(int u,int v)
    {
        x[++s].n=x[u].f;
        x[x[u].f=s].v=v;
    }
    void dfs(int u)
    {
        vis[u]=1;
        for(int i=x[u].f;i;i=x[i].n)
            if(!vis[x[i].v]) dfs(x[i].v);
    }
    int main()
    {
        int n;
        while(scanf("%d",&n)&&n)
        {
            memset(x,0,sizeof(x));
            memset(vis,0,sizeof(vis));
            memset(to,0,sizeof(to));
            s=0;
            int m,bj=0;
            scanf("%d",&m);
            while(m--)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                add(u,v);add(v,u);
                ++to[u];++to[v];
            }
            for(int i=1;i<=n;++i)
                if(to[i]&1) ++bj;
            if(bj)
            {
                printf("0
    ");
                continue;
            }
            vis[1]=1;dfs(1);
            for(int i=1;i<=n;++i)
                if(!vis[i])
                {
                    bj=1;
                    break;
                }
            bj?printf("0
    "):printf("1
    ");
        }
        return 0;
    } 

    poj2337

    http://poj.org/problem?id=2337

    一道单词接龙题,问能不能找到一个接龙完美包含所有单词且每个单词只出现一次。若有输出其中字典序最小的。

    而这些单词就是连接首尾字母的边所以只要求出欧拉回路的走法即可

    对于字典序尽量小,要把边按照字典序从大到小排序再添加(如果有疑问可以调试下这个样例1 6 ab ba bc bd db cb)

    其余细节在代码中有注释。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    struct X
    {
        int v,f,n;
        bool vis;
    }x[1005];
    int rd[30],cd[30],fa[30],q[1005],sl;
    bool cx[30];
    string c[1005];
    bool cmp(const string &a,const string &b)
    {
        return a>b;
    }
    int fi(int a)
    {
        int b=a;
        while(fa[a]!=a) a=fa[a];
        while(fa[b]!=a)
        {
            int t=fa[b];
            fa[b]=a;
            b=t;
        }
        return a;
    }
    void dfs(int u)
    {
        for(int i=x[u].f;i;i=x[i].n)
            if(!x[i].vis)
            {
                x[i].vis=1;
                dfs(x[i].v);
                q[++sl]=i;//倒序记录走过的边,建议不懂可以调试观察
            }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,qd=0,zd=0,sf=0,jl=0;
            scanf("%d",&n);
            memset(x,0,sizeof(x));
            memset(rd,0,sizeof(rd));
            memset(cd,0,sizeof(cd));
            memset(cx,0,sizeof(cx));
            for(int i=1;i<=26;++i) fa[i]=i;
            for(int i=1;i<=n;++i) cin>>c[i];
            sort(c+1,c+n+1,cmp);
            for(int i=1;i<=n;++i) 
            {
                int u=c[i][0]-'a'+1;
                x[i].v=c[i][c[i].size()-1]-'a'+1;
                x[i].n=x[u].f;
                x[u].f=i;
                ++cd[u];
                ++rd[x[i].v];
                cx[x[i].v]=cx[u]=1;
                fa[fi(x[i].v)]=fi(u);//用并查集判断图的联通性
            }
            sl=0;
            for(int i=1;i<=26&&!sf;++i)
                if(cd[i]+1==rd[i]&&!zd) zd=i;
                else if(rd[i]+1==cd[i]&&!qd) qd=i;//若有rd+1==cd的点必须为起点
                else if(cd[i]!=rd[i]) sf=1;
            for(int i=1;i<=26&&!sf;++i)
                if(cx[i])
                    if(!jl) jl=fi(i);
                    else if(jl!=fi(i)) sf=1;
            if(sf)
            {
                printf("***
    ");
                continue;
            }
            if(!qd) 
                for(int i=1;!qd;++i) if(cx[i]) qd=i;//若没有rd+1==cd的点,那么应该选择出现过的最小字母对应点开始
            dfs(qd);
            for(int i=sl;i>=1;--i)
            {
                cout<<c[q[i]];
                i==1?printf("
    "):printf(".");    
            }
        }
        return 0;
    }

    推荐题目:http://www.cnblogs.com/bzmd/p/7002979.html

  • 相关阅读:
    BFS visit tree
    Kth Largest Element in an Array 解答
    Merge k Sorted Lists 解答
    Median of Two Sorted Arrays 解答
    Maximal Square 解答
    Best Time to Buy and Sell Stock III 解答
    Best Time to Buy and Sell Stock II 解答
    Best Time to Buy and Sell Stock 解答
    Triangle 解答
    Unique Binary Search Trees II 解答
  • 原文地址:https://www.cnblogs.com/bzmd/p/6849674.html
Copyright © 2011-2022 走看看