欧拉回路和欧拉路径

几个入门的题目:

hdu 1878

判定一个图是否存在欧拉回路。

直接判断图是否连通和每个点的度数是否为偶数就行了。(可用并查集判断连通,也可以用dfs)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1100;
int in[maxn];
int F[maxn];
void init()
{
    memset(F, -1, sizeof(F));
}
int find(int x)
{
    if (F[x] == -1) return x;
    return F[x] = find(F[x]);
}
void Union(int x, int y)
{
    int tx = find(x);
    int ty = find(y);
    if (tx != ty)
        F[tx] = ty;
}
int main()
{
    int n, m;
    while (~scanf("%d", &n) && n)
    {
        memset(in, 0, sizeof(in));
        scanf("%d", &m);
        int u, v;
        init();
        for (int i = 1; i <= m; i++)
        {
            scanf("%d %d", &u, &v);
            Union(u, v);
            ++in[u];
            ++in[v];
        }
        int flag = 1;
        for (int i = 1; i <= n; i++)
        {
            if (in[i] % 2)
            {
                flag = 0;
                break;
            }
        }
        if (flag)
        {
            for (int i = 2; i <= n; i++)
            {
                if (find(i) != find(1))
                {
                    flag = 0;
                    break;
                }
            }
        }
        printf("%d\n", flag);
    }
    return 0;
}

poj 1041

求欧拉回路。

dfs回溯的时候求,因为是个回路,所以要在回溯的时候加到 答案 数组当中

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 2000;
struct Edge {
    int to, next, id;
}edge[5000000];
int tot;
int head[maxn];
int in[maxn];
int F[maxn];

void init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
    memset(in, 0, sizeof(in));
    memset(F, -1, sizeof(F));
}
void addedge(int u, int v, int id)
{
    edge[tot].to = v;
    edge[tot].id = id;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int find(int x)
{
    if (F[x] == -1) return x;
    return F[x] = find(F[x]);
}

void Union(int x, int y)
{
    int tx = find(x);
    int ty = find(y);
    if (tx != ty)
        F[tx] = ty;
}

int n;
bool check()
{
    for (int i = 1; i <= n; i++)
        if (in[i] & 1 || in[i] == 0)
            return false;
    for (int i = 2; i <= n; i++)
        if (find(i) != find(1))
            return false;
    return true;
}

int S[5000000];
bool vis[5000000];
int top;
void dfs(int u)
{
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        if (vis[i]) continue;
        vis[i] = true;
        vis[i ^ 1] = true;
        dfs(edge[i].to);
        S[top++] = i;
    }
}
int main()
{
    int u, v, id;
    while (~scanf("%d %d", &u, &v))
    {
        if (u == 0 && v == 0) break;
        scanf("%d", &id);
        n = -1;
        init();
        addedge(u, v, id);
        addedge(v, u, id);
        Union(u, v);
        n = max(n, u);
        n = max(n, v);
        ++in[u];
        ++in[v];
        while (~scanf("%d %d", &u, &v))
        {
            if (u == 0 && v == 0) break;
            scanf("%d", &id);
            addedge(u, v, id);
            addedge(v, u, id);
            Union(u, v);
            n = max(n, u);
            n = max(n, v);
            ++in[u];
            ++in[v];
        }
        if (!check())
            puts("Round trip does not exist.");
        else
        {
            top = 0;
            memset(vis, false, sizeof(vis));
            dfs(1);
            for (int i = 0; i < top; i++)
                printf("%d%c", edge[S[i]].id, i == top - 1 ? '\n' : ' ');
        }
    }
    return 0;
}

uva10054

求欧拉回路。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int maxn = 2000;
struct Edge {
    int to, next;
}edge[1000100];
int tot;
int head[maxn];
int in[maxn];
int F[maxn];

void init()
{
    tot = 0;
    memset(head, -1, sizeof(head));
    memset(in, 0, sizeof(in));
    memset(F, -1, sizeof(F));
}
void addedge(int u, int v)
{
    edge[tot].to = v;
    edge[tot].next = head[u];
    head[u] = tot++;
}

int find(int x)
{
    if (F[x] == -1) return x;
    return F[x] = find(F[x]);
}

void Union(int x, int y)
{
    int tx = find(x);
    int ty = find(y);
    if (tx != ty)
        F[tx] = ty;
}

int n;
bool color[100];
int st;
bool check()
{
    for (int i = 1; i <= n; i++)
        if (color[i])
            if (in[i] & 1 || in[i] == 0)
                return false;
    for (int i = 1; i <= n; i++)
        if (color[i])
            if (find(i) != find(st))
                return false;
    return true;
}
Edge ans[1000010];
bool vis[1000010];
int top;
void dfs(int u)
{
    for (int i = head[u]; i != -1; i = edge[i].next)
    {
        if (vis[i]) continue;
        vis[i] = true;
        vis[i ^ 1] = true;
        dfs(edge[i].to);
        ans[top].to = u;
        ans[top++].next = edge[i].to;
    }
}
int main()
{
    int T, kase = 0;
    scanf("%d", &T);
    while (T--)
    {
        memset(color, false, sizeof(color));
        init();
        int m;
        scanf("%d", &m);
        int u, v;
        n = -1;
        for (int i = 0; i < m; i++)
        {
            scanf("%d %d", &u, &v);
            n = max(n, u);
            n = max(n, v);
            addedge(u, v);
            addedge(v, u);
            Union(u, v);
            ++in[u];
            ++in[v];
            color[u] = color[v] = true;
        }
        st = u;
        if (!check())
            printf("Case #%d\nsome beads may be lost\n", ++kase);
        else
        {
            top = 0;
            memset(vis, false, sizeof(vis));
            dfs(st);
            printf("Case #%d\n", ++kase);
            for (int i = top - 1; i >= 0; i--)
                printf("%d %d\n", ans[i].to, ans[i].next);
        }
        if (T)
            printf("\n");
    }
    return 0;
}

 

posted @ 2015-10-23 21:03  Howe_Young  阅读(918)  评论(0编辑  收藏  举报