CCF-CSP solution to a problem 201512-4 Delivery

Seeking lexicographically smallest Euler Road.

It does not seem to use \ (Fluery \) algorithm ( \ (O (E ^ 2) \) ). \ (Fluery \) idea of the algorithm is: side extension application is not possible to remove the bridge has gone through the side of the chart (cut). Each step must determine whether it is cut, it should time out.

Using \ (Hierholzer \) algorithm ( \ (O (V + E) \) ), also known as progressive insertion loop method. Ideas see the code. Note Depending on the meaning of the questions, each chosen not gone through the apex of the smallest side extension application.

Note No. 1 subject of the request from the node.

Euler road conditions exist:

Undirected graph:

The presence of Euler: original communication, each node of the nodes are even.

Euler presence passage: the presence of Euler, or picture communication, there are two nodes of odd nodes, the other nodes are the nodes of the coupling.

Directed graph:

The presence of Euler: Fig group (with the side edges become undirected) communication, the degree of each node is equal to a degree.

Euler presence passage: the presence of Euler or FIG communication group, the node has a degree equal to a +1, a node has an equal degree of penetration of +1, the other nodes is equal to the degree.

#include<bits/stdc++.h>
const int maxn = 10000;
const int maxm = 100000;

using namespace std;

int to[maxm * 2 + 10];
int vis[maxm * 2 + 10];
int nex[maxm * 2 + 10];
int head[maxn + 10], cnt = 0;

void addEdge(int a, int b)
{
    to[cnt] = b;
    vis[cnt] = 0;
    nex[cnt] = head[a];
    head[a] = cnt++;
    to[cnt] = a;
    vis[cnt] = 0;
    nex[cnt] = head[b];
    head[b] = cnt++;
}

int degree[maxn + 10];

int vis1[maxn + 10], num = 0;

void dfs(int x)
{
    vis1[x] = 1;
    num++;
    for (int i = head[x]; i != -1; i = nex[i])
    {
        int l = to[i];
        if (!vis1[l])
            dfs(l);
    }
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);

    memset(head, -1, sizeof(head));
    memset(degree, 0, sizeof(degree));
    for (int i = 1, a, b; i <= m; i++)
    {
        scanf("%d%d", &a, &b);
        addEdge(a, b);
        degree[a]++;
        degree[b]++;
    }

    memset(vis1, 0, sizeof(vis1));
    dfs(1);

    int odd = 0;
    for (int i = 1; i <= n; i++)
    {
        if (degree[i] % 2)
            odd++;
    }

    if (num == n && (odd == 0 || (odd == 2 && degree[1] % 2)))
    {
        stack<int> s1, s2;
        s1.push(1);
        while (!s1.empty())
        {
            int x = s1.top();
            int y = -1, ii = -1;
            for (int i = head[x]; i != -1; i = nex[i])
            {
                if (vis[i])
                    continue;
                int l = to[i];
                if (y == -1 || y > l)
                    y = l, ii = i;
            }
            if (y == -1)
            {
                s2.push(x);
                s1.pop();
            }
            else
            {
                vis[ii] = vis[ii ^ 1] = 1;
                s1.push(y);
            }
        }
        bool first = true;
        while (!s2.empty())
        {
            if (first)
            {
                printf("%d", s2.top());
                s2.pop();
                first = false;
            }
            else
            {
                printf(" %d", s2.top());
                s2.pop();
            }
        }
        printf("\n");
    }
    else
    {
        printf("-1\n");
    }

    return 0;
}

Guess you like

Origin www.cnblogs.com/acboyty/p/11444137.html
Recommended