• AcWing 1124. 骑马修栅栏


    题目传送门

    • 本题数据量较小,可以使用邻接矩阵
    • 要求输出最小字典序,我们需要保证由小点出发,一路上从小枚举到大
    • 考查无向图求欧拉路径的办法

    一、邻接矩阵模板

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 510;
    
    int n = 500, m;
    int g[N][N];      //邻接矩阵
    vector<int> path; //欧拉路径
    int d[N];         //度数
    void dfs(int u) {
        //我们在遍历的时候,把走过的路删掉,这样就不会重复走了,而且省去了反复横跳的风险
        for (int i = 1; i <= n; i++)  //枚举每个点
            if (g[u][i]) {            //如果u->i存在一条边
                g[u][i]--, g[i][u]--; //那么我们删除掉正向边和反向边
                dfs(i);               //继续搜索
            }
        path.push_back(u); //记录这个点
    }
    
    int main() {
        cin >> m;
        while (m--) {
            int a, b;
            cin >> a >> b;
            g[a][b]++, g[b][a]++; //邻接矩阵记录无向边
            d[a]++, d[b]++;       //记录无向图的度数
        }
    
        //下面这样去费劲找到第一个可行的度数为奇数的点,是为了最小字典序
        //较小编号作为起点
        int start = 1;               //默认从1号点出发
        while (!d[start]) start++;   //如果是孤立点,那么继续尝试其它点
        for (int i = 1; i <= n; i++) //尝试找到度数为奇数的点
            if (d[i] % 2) {
                start = i;
                break;
            }
        //无向图开始查找欧拉路径
        dfs(start);
        //输出欧拉路径
        for (int i = path.size() - 1; i >= 0; i--) printf("%d\n", path[i]);
        return 0;
    }
    

    二、邻接表解法

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 5e3 + 10;
    typedef pair<int, int> PII;
    int n = 500, m;
    vector<int> path;
    bool st[N];
    int d[N];
    int h[N], e[N], ne[N], idx;
    void add(int a, int b) {
        e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    
    void dfs(int u) {
        vector<PII> a;
        for (int i = h[u]; ~i; i = ne[i]) a.push_back({e[i], i});
        sort(a.begin(), a.end()); //从小到大排序
        for (int i = 0; i < a.size(); i++) {
            int edge = a[i].second;
            if (st[edge] || st[edge ^ 1]) continue;
            st[edge] = st[edge ^ 1] = true;
            dfs(a[i].first);
        }
        path.push_back(u);
    }
    int main() {
        memset(h, -1, sizeof h);
        cin >> m;
        while (m--) {
            int a, b;
            cin >> a >> b;
            add(a, b), add(b, a);
            d[a]++, d[b]++;
        }
    
        int start = 1;
        while (!d[start]) start++;
        for (int i = 1; i <= n; i++)
            if (d[i] & 1) {
                start = i;
                break;
            }
        dfs(start);
        for (int i = path.size() - 1; i >= 0; i--) cout << path[i] << endl;
        return 0;
    }
    
  • 相关阅读:
    iOS8及以后 地图定位当前城市
    UITextView换行问题解决办法
    使用七牛上传图片代码,导入文件常遇问题解决方法
    CocoaPods安装和使用
    Xcode7真机测试
    Label 添加表情图片
    TTTAttributedLabel使用介绍(转)
    带有中文的url和NSString中文的转换
    正则表达式的使用 选取有用数据
    导航网格配置笔记
  • 原文地址:https://www.cnblogs.com/littlehb/p/16112674.html
Copyright © 2020-2023  润新知