zoukankan      html  css  js  c++  java
  • 欧拉通路是否存在

    //题目:一个字符串数组例如 abcd dcsg gec就输出true否则输出false;

    这个问题就转化成一个图中是否存在欧拉通路问题。这里主要考虑的情况就是存在环的情况,所以当存在环的时候用深度遍历,只要看从一个点能不能经过所有点即可,选择dfs的起点的话分两种情况,如果有度为1的点就选择其中度为1的点,如果度都大于1的话就遍历所有点。代码如下:

    #include <iostream>
    #include <cstring>
    #include <vector>
    #define DEBUG
    using namespace std;
    
    const int MAX = 10240;
    
    int N, M, pCnt[MAX];
    int pMap[MAX][MAX];
    vector<int> pVec;
    vector<bool>state(7,false);
    void dfs(int x);
    void Euler_Circuit();
    vector<int>tmp;
    bool flag = false;
    int main()
    {
    #ifdef DEBUG
        FILE *in;
        FILE *out;
        freopen_s(&in, "in.txt", "r", stdin);
        freopen_s(&out, "out.txt", "w", stdout);
    #endif
        cin >> N >> M;
        memset(pMap, 0, sizeof(pMap));
        for (int i = 1; i <= M; i++)
        {
            int s, e;
            cin >> s >> e;
            pMap[s][e] = pMap[e][s] = 1;    // 无向图
        }
        Euler_Circuit();
        if (flag)cout << "true" << endl;
        else cout << "false" << endl;
    #ifdef DEBUG
        fclose(in);
        fclose(out);
    #endif
        return 0;
    }
    
    void Euler_Circuit()
    {
        int nStart = 1, nOddNum = 0;    // nStart保存起点,nOddNum保存有几个顶点有奇数度
        memset(pCnt, 0, sizeof(pCnt));
        for (int i = 1; i <= N; i++)
        {
            for (int j = 1; j <= N; j++)
            {
                pCnt[i] += pMap[i][j];        // 计算各个顶点的度
            }
        }
    
        for (int i = 1; i <= N; i++)    // 统计奇数度顶点的个数
        {
            if (pCnt[i] & 1)
            {
                nStart = i;
                
                nOddNum++;
            }
        }
        for (int i = 1; i <= N; i++)
        {
            bool flag = false;
            if (pCnt[i] == 1)
            {
                if (!flag)
                {
                    nStart = i;
                    flag = true;
                }
                
                tmp.push_back(i);
            }
        }
        if (tmp.size() >2 || tmp.size()==1)return;
        pMap[tmp[0]][tmp[1]] = 1;
        pMap[tmp[1]][tmp[0]] = 1;
        if (nOddNum == 1)        
        {
            return;
        }
        else
        {
            if (!tmp.size())
            {
                for (int i = 1; i <= N; i++)
                {
                    dfs(i);
                }
            }
            else
            {
                dfs(nStart);
            }
            
        }
    }
    
    void dfs(int x)
    {
        if (pVec.size() == N && !flag)
        {
            flag = true;
            for (int i = 0; i < N; i++)
            {
                cout << pVec[i] << " ";
            }
            cout << endl;
        }
        if (state[x])return;
        for (int i = 1; i <= N; i++)
        {
            if (pMap[x][i] != 0)
            {
                state[x] = true;
                pVec.push_back(x);
                dfs(i);
                state[x] = false;
                pVec.pop_back();
            }
        }
        
    }
  • 相关阅读:
    hdu 2227
    小A的数学题
    E
    F
    C
    Ping-Pong (Easy Version)的解析
    余数之和BZOJ1257
    大数求余
    数论学习 算法模板(质数,约数)
    Acwing 197. 阶乘分解
  • 原文地址:https://www.cnblogs.com/mahaitao/p/5796378.html
Copyright © 2011-2022 走看看