UVaOJ 10596 - Morning Walk

本文介绍了一种解决特定图论问题的算法——欧拉回路算法。通过一个坏孩子逛遍城市每条街道的问题背景引入,详细阐述了如何判断一个无向图是否存在欧拉回路,并提供了一个实现该算法的具体代码示例。


——by A Code Rabbit


Description

有一个坏孩子喜欢逛遍城市的大街小巷,好吧就逛吧。
输入有多少个地点和好多条街道。
输出能否走遍每条街。


Types

Date Structure :: Graphs


Analysis

按题目的意思,这个孩子走完街道是要回家的。

所以求得是欧拉回路。

据说 toolkit 标程是有问题的,但是不影响我们A题。

不过要注意一点,如果有一条街道两端都是同一个地方,虽然不合情理,但是也是一个需要被遍历的街道。

当然如果按欧拉回路的模板,是刚好可以覆盖这种情况的。


Solution

// UVaOJ 10596
// Morning Walk
// by A Code Rabbit


#include <cstdio>
#include <cstring>


const int LIMITS_N = 250;
const int LIMITS_R = 10086;


int graph[LIMITS_N][LIMITS_N];
int n, r;


int order[LIMITS_N];


bool visit[LIMITS_R];
int sum;


void Process(int u, int v);
bool MatchConditions();
void Search(int pos);


int main() {
    while (scanf("%d%d", &n, &r) != EOF) {
        // INIT.
        memset(graph, 0, sizeof(graph));
        memset(order, 0, sizeof(order));
        memset(visit, false, sizeof(visit));
        sum = 0;
        // Inputs.
        for (int i = 0; i < r; ++i) {
            int u, v;
            scanf("%d %d", &u, &v);
            Process(u, v);
        }
        // Judge whether the orders match conditions.
        bool is_euler_circuit = MatchConditions();
        // Judge whether the undirected graph is connected.
        if (is_euler_circuit) {
            Search(0);
            if (sum != n) {
                is_euler_circuit = false;
            }
        }
        // Outputs.
        printf("%s\n", is_euler_circuit ? "Possible" : "Not Possible");
    }


    return 0;
}


void Process(int u, int v) {
    ++order[u];
    ++order[v];
    ++graph[u][v];
    ++graph[v][u];
}


bool MatchConditions() {
    for (int i = 0; i < n; ++i) {
        if (order[i] % 2) {
            return false;
        }
    }
    return true;
}


void Search(int pos) {
    visit[pos] = true;
    ++sum;
    for (int i = 0; i < n; ++i) {
        if (graph[pos][i] && !visit[i]) {
            Search(i);
        }
    }
}


下载PDF

参考资料:无


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值