模板整理1 欧拉图的判定及输出路径(输出路径按字典序输出)

如何判断图是否有欧拉回路或者欧拉路径?

无向图:因为欧拉路径中,除了起点与终点以外,任意点的“进”“出”次数相等,所以除了两个点为奇点(度数为奇数的点)(终点和起点)以外,其它点的度数均为偶数。

如果是欧拉回路,奇点的个数应该为0。

有向图:欧拉路径中,最多只有两个点的入度不等于出度。起点出度比入度大1,终点入度比出度大1。

如果是欧拉回路,所有点的 入度=出度 。

如何输出路径:

必须保证是欧拉图

#include<bits/stdc++.h>
using namespace std;
const int N=1025;
multiset<int> to[N];
multiset<int> ::iterator pos;
int len[N];
int road[N],k;
void dfs(int x)
{
    for(pos=to[x].begin();pos!=to[x].end();pos=to[x].begin())
    {
        int u=*pos;
        to[x].erase(pos);
        to[u].erase(to[u].find(x));
        dfs(u);
    }
    road[k++]=x;
}

int main(){
    int m,a,b;
    scanf("%d",&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        len[a]++,len[b]++;
        to[a].insert(b);
        to[b].insert(a);
    }
    int s=-1,e=-1;
    for(int i=1;i<=1024;i++)
        if(len[i]%2==1)
        {
            if(s==-1)
            s=i;
            else if(e==-1)
            e=i;
            else
            exit(1);
        }
    if(s==-1)s=1;
    dfs(s);
    for(k=k-1;k>=0;k--)
        printf("%d\n",road[k]);
    return 0;
}
欧拉图判定可以使用Fleury算法,具体实现如下: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #define MAXV 1000 //邻接矩阵存图 typedef struct Graph { int nv; //顶点数 int ne; //边数 int adj[MAXV][MAXV]; //邻接矩阵 } Graph; //创建一张图 Graph* createGraph(int nv) { Graph* graph = (Graph*)malloc(sizeof(Graph)); graph->nv = nv; graph->ne = 0; int i, j; for (i = 0; i < nv; i++) { for (j = 0; j < nv; j++) { graph->adj[i][j] = 0; } } return graph; } //插入一条边 void insertEdge(Graph* graph, int v, int w) { graph->adj[v][w] = graph->adj[w][v] = 1; graph->ne++; } //删除一条边 void removeEdge(Graph* graph, int v, int w) { graph->adj[v][w] = graph->adj[w][v] = 0; graph->ne--; } //判断是否为欧拉图 bool isEuler(Graph* graph) { int i, j, oddCount = 0; for (i = 0; i < graph->nv; i++) { int degree = 0; for (j = 0; j < graph->nv; j++) { degree += graph->adj[i][j]; } if (degree % 2 == 1) { oddCount++; } } if (oddCount == 0 || oddCount == 2) { return true; } else { return false; } } //DFS遍历图 void dfs(Graph* graph, int v, bool visited[]) { visited[v] = true; int i; for (i = 0; i < graph->nv; i++) { if (graph->adj[v][i] && !visited[i]) { dfs(graph, i, visited); } } } //判断是否为连通图 bool isConnected(Graph* graph) { bool visited[MAXV] = {false}; int i; for (i = 0; i < graph->nv; i++) { if (!visited[i]) { dfs(graph, i, visited); break; } } if (i == graph->nv) { return true; } else { return false; } } //输出欧拉回路 void printEulerCircuit(Graph* graph, int v) { int i, j; for (i = 0; i < graph->nv; i++) { if (graph->adj[v][i]) { removeEdge(graph, v, i); printEulerCircuit(graph, i); } } printf("%d ", v); } //输出所有欧拉图 void printAllEuler(Graph* graph) { if (!isConnected(graph) || !isEuler(graph)) { printf("No Euler graph exists!\n"); return; } int i, j; for (i = 0; i < graph->nv; i++) { for (j = i+1; j < graph->nv; j++) { if (graph->adj[i][j]) { removeEdge(graph, i, j); if (!isEuler(graph)) { insertEdge(graph, i, j); } else { printf("Euler graph: "); printEulerCircuit(graph, i); printf("\n"); insertEdge(graph, i, j); } } } } } int main() { Graph* graph = createGraph(5); insertEdge(graph, 0, 1); insertEdge(graph, 0, 2); insertEdge(graph, 1, 2); insertEdge(graph, 1, 3); insertEdge(graph, 2, 3); insertEdge(graph, 2, 4); insertEdge(graph, 3, 4); printAllEuler(graph); return 0; } ``` 在这个例子中,我们创建了一张5个顶点的图,插入了7条边。程序会输出所有的欧拉图。对于这张图来说,它是一张欧拉图输出结果为: ``` Euler graph: 0 2 1 3 4 ``` 这个结果表示了一条欧拉回路,其中顶点0是起点和终点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值