欧拉回路 (Euler Circuit) POJ 1780

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

相关概念和算法参考:

https://www.math.ku.edu/~jmartin/courses/math105-F11/Lectures/chapter5-part2.pdf

http://web.info.uvt.ro/~idramnesc/GTC/Lecture10_Isabela.pdf

#include <cstdio>
#include <cstring>
using namespace std;

#define MAXN    100000
#define MAXM    1000000

struct edge {
    int id;
    int to;
    int next;
};

int adjlist[MAXN]; int nnodes;
edge edges[MAXM]; int nedges;

int stack[MAXM]; int top;
int visited[MAXM];
int result[MAXM + 10]; int nres;

int n; // input

void graph_init() {
    nnodes = 1;
    int k = n - 1;
    while (k--) nnodes *= 10;
    int size = nnodes * sizeof(int);
    memset(adjlist, -1, size);
    nedges = 0;
    top = -1;
    memset(visited, 0, size * 10);
    nres = 0;
}

void add_edge(int u, int v, int eid) {
    edges[nedges].id = eid;
    edges[nedges].to = v;
    edges[nedges].next = adjlist[u];
    adjlist[u] = nedges++;
}

void graph_dfs() {
    stack[++top] = 0;
    printf("%0*d", n-1, 0);
    visited[0] = 1;
    while (top >= 0) {
        int u = stack[top];
        for (int i = adjlist[u]; i != -1; i = edges[i].next) {
            int eid = edges[i].id;
            int v = edges[i].to;
            if (visited[eid] == 0) {
                visited[eid] = 1;
                stack[++top] = v;
                goto cont_while;
            }
        }
        top--;
        result[nres++] = u;
    cont_while: ;
    }
    for (int i = nres - 1; i >= 0; i--) 
        printf("%d", result[i] % 10);
    printf("\n");
}

void solve() {
    graph_init();
    for (int u = 0; u < nnodes; u++) {
        int w = u % (nnodes / 10);
        for (int j = 9; j >= 0; j--) { 
            int v = w * 10 + j;
            add_edge(u, v, u*10+j);
        }
    }
    graph_dfs();
}

int main() {
    while (scanf("%d", &n) != EOF) {
        if (n == 0) break;
        if (n == 1) printf("0123456789\n");
        else solve();
    }
    return 0;
}

 

posted @ 2015-09-27 23:12  william-cheung  阅读(519)  评论(0编辑  收藏  举报