欧拉回路 (Euler Circuit)

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

相关概念和算法参考:https://www.math.ku.edu/~jmartin/courses/math105-F11/Lectures/chapter5-part2.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;
}
时间: 2024-10-12 20:03:17

欧拉回路 (Euler Circuit)的相关文章

UVa 10735 (混合图的欧拉回路) Euler Circuit

题意: 给出一个图,有的边是有向边,有的是无向边.试找出一条欧拉回路. 分析: 按照往常的思维,遇到混合图,我们一般会把无向边拆成两条方向相反的有向边. 但是在这里却行不通了,因为拆成两条有向边的话,就表示这个边能“在两个相反方向各经过一次”. 而题意是这个边只能经过一次. 假设图中存在欧拉回路,则所有点的出度out(i) 等于 入度in(i) 不妨这样,先将所有的无向边任意定向,对于out(u) > in(u)的点,可以将已经定向的无向边u->v反向为v->u,这样out(u) - i

10.5欧拉路径和欧拉回路(Euler Paths and Circuits)

10.5欧拉路径和欧拉回路(Euler Paths and Circuits) 引入:七桥问题 "一笔画"-->针对边而言 欧拉图(Eulerian graph) 图G的欧拉回路(Euler circuit)指的是遍历G中每一条边的简单回路(simple circuit), 这样的轨迹称为欧拉环游(Euler tour) 图G的欧拉路径(Euler path)指的是遍历G中每一条边的简单路径(simple path), 这样的轨迹称为欧拉轨迹(Euler trail) 有欧拉回路

UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)

题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制方向而已,那么这个情况下就不能拆边.不妨先按照所给的start和end的顺序,初步定下该无向边的顺序(若不当,一会再改).那么有个问题,我们需要先判断其是否存在欧拉回路先. 混合图不满足欧拉回路因素有:(1)一个点的度(无论有无向)是奇数的,那么其肯定不能满足出边数等于入边数.(2)有向边的出入度过

UVa 10735 - Euler Circuit(最大流 + 欧拉回路)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1676 题意: 给出一个V个点和E条边(1≤V≤100,1≤E≤500)的混合图(即有的边是无向边,有的边是有向边),试求出它的一条欧拉回路,如果没有,输出无解信息.输入保证在忽略边的方向之后图是连通的. 分析: 很多混合图问题(例如,混合图的最短路)都可以转化为有向图问题,方法是把

UVa10735 Euler Circuit (混合图的欧拉回路,最大流)

链接:http://vjudge.net/problem/UVA-10735 分析:题目保证底图联通,所以连通性就不用判断了.其次,不能把无向边转成有向边来做,因为本题中无向边只能经过一次,而拆成两条有向边之后变成了“沿着两个相反方向各经过一次”,所以本题不能拆边,而只能给边定向.首先我们给无向边任意定向,比如无向边(u,v),可以将其定向为u->v,于是u的出度和v的入度多1(在保证出入度相等的前提下,后者等价于出度少1),那我们这样随意定向以后反悔了怎么办呢?比如最后u的出度为4,入度为2,

poj2284 That Nice Euler Circuit(欧拉公式)

题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k(k≥2)个连通分支的平面图G,有:n-m+r=k+1. 题意:给出连通平面图的各顶点,求这个欧拉回路将平面分成多少区域. 题解:根据平面图的欧拉定理“n-m+r=2”来求解区域数r. 顶点个数n:两两线段求交点,每个交点都是图中的顶点. 边数m:在求交点时判断每个交点落在第几条边上,如果一个交点落在

UVA LIVE-3263 - That Nice Euler Circuit

画一个顶点为偶数的封闭的二维图,当然.这个图能够自交,给出画的过程中的一些轨迹点.求出这个图把二次元分成了几部分,比如三角形把二次元分成了两部分. 这个的话,有图中顶点数+部分数-棱数=2的定律,这是核心思想.也就是所谓的欧拉定律拓扑版,好吧,事实上细致想想也是可以想出这个规律来的. 做出这题纯属意外,因为给的点的坐标全是用整数表示,为了不用考虑精度问题,一開始.我就想仅仅用这些点.就是说不再算出其他交点之类的,就把答案算出, 由于当前轨迹与之前轨迹无非三种情况:规范与不规范相交,不相交 不相交

【UVA】1342 - That Nice Euler Circuit(几何+欧拉定理)

E 为边数 ,V 为点数,F为面数 那么 F = E + 2 - V(其中包括了一个无限大的面) 这道题被自己的习惯坑了一下#define MAXD 300 + 10 和#define MAXD 310 是不一样的 14113235 1342 That Nice Euler Circuit Accepted C++ 0.082 2014-08-29 15:12:20 自己的代码: #include<cstdio> #include<cstring> #include<iost

UVALive - 3263 That Nice Euler Circuit (几何)

UVALive - 3263 That Nice Euler Circuit (几何) ACM 题目地址: UVALive - 3263 That Nice Euler Circuit 题意: 给出一个点,问连起来后的图形把平面分为几个区域. 分析: 欧拉定理有:设平面图的顶点数.边数.面数分别V,E,F则V+F-E=2 大白的题目,做起来还是很有技巧的. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: LA3263.cpp * C