uva10129 欧拉回路 判断出入度数 连通性 遍历压栈

博客探讨了如何解决UVA10129问题,即欧拉回路的判断。文章指出,当图有0个或2个奇度数点时存在欧拉回路。内容包括求度数的方法、判断连通性的策略以及通过遍历找到回路的技巧。此外,博客还提供了连通性判断的注意事项和动态存图的建议,并分享了一段可读性较高的AC代码作为参考。
摘要由CSDN通过智能技术生成

欧拉回路(一笔画问题):
求度数>>连通性>>遍历找回路

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19451
欧拉回路:
有0个或2个奇度数点,则一定有欧拉回路。
求度数>>连通性>>遍历找回路
求度数:
1.设置两个数组在输入时判断。(推荐)
2.反向查找图。
连通性:
只需要判断无向图的连通性,遍历之后配合审查函数,审查函数配合出入度数组。
有向图如要利用保存的图,可以将图的反向设置为–,正向为++。
根据规模和应用方法灵活运用矩阵和vector动态存图,可以有限矩阵保存。
其它理解见我的注释:

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

#define MAX_V 26  
#define MAX_LEN 1005  

int G[MAX_V][MAX_V];  
int inDeg[MAX_V];  
int outDeg[MAX_V];  
int vis[MAX_V];  

void DFS(int);  
bool okDeg();  
bool okDFS();  

int main()  
{  
    int cases;  
    scanf("%d", &cases);  
    while (cases--) {  
        // init  
        memset(G, 0, sizeof(G));  
        memset(inDeg, 0, sizeof(inDeg));  
        memset(outDeg, 0, sizeof(outDeg));  
        memset(vis, 0, sizeof(vis));  
        int edge, star;  
        scanf("%d%*c", &edge);  

        // enter  
        for (int i = 0; i < edge; i++) {  
            char str[MAX_LEN];  
            gets(str);  
            int u = str[0] - 'a';  
            int v = str[strlen(str) - 1] - 'a';  
            outDeg[u]++;  
            inDeg[v]++;  
            G[u][v]++;  
            G[v][u]++;  
            star = u;  
        }  

        // judge  
        DFS(star);  
        if (okDeg() && okDFS()) {  
            printf("Ordering is possible.\n");  
        }else {  
            printf("The door cannot be opened.\n");  
        }  

        // end a case  

    }  

    return 0;  
}  

void DFS(int u)  //遍历整个图,配合okDFS判断无向图的连通性
{  
    vis[u] = true;  
    for (int i = 0; i < MAX_V; i++) {  
        if (G[u][i] > 0) {  
            G[u][i]--;  
            G[i][u]--;  
            DFS(i);  
        }  
    }  
}  

bool okDeg()  
{  
    bool markStar = false;  
    bool markEnd = false;  

    for (int i = 0; i < MAX_V; i++) {  
        if (inDeg[i] != outDeg[i]) {  
            if (!markEnd && inDeg[i] == outDeg[i] + 1) {  
                markEnd = true;  
            }else if (!markStar && inDeg[i] + 1 == outDeg[i]){  
                markStar = true;  
            }else {  
                return false;  
            }  
        }  
    }  

    return true;  
}  
bool okDFS()  //配合DFS判断无向图的连通性
{  
    for (int u = 0; u < MAX_V; u++) {  
        if (inDeg[u] + outDeg[u]) {  //确定这个节点存在
            if (vis[u] == false) {  
                return false;  
            }  
        }  
    }  

    return true;  
}  

这道题没有涉及欧拉回路的遍历,于是我额外贴上刘汝佳的代码。

void euler(int u)//遍历,有向图需要找到起点
{
    for(int v = 0; v < n; ++v)
        if(G[u][v] && !vis[u][v])//节点存在且未访问
        {
            vis[u][v] = vis[v][u] = 1;//标记访问过
            euler(v);//先遍历后压栈
            printf("%d %d\n",u,v);//压栈,当提前出局也压栈,一定是最后一条路
        }
}

这份代码是在网上找的可读性比较高的一份ac代码,当然这篇blog的注释和讲解是我自己的理解。
http://blog.csdn.net/mistkafka/article/details/9345877

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值