【ACWing】1124. 骑马修栅栏

题目地址:

https://www.acwing.com/problem/content/1126/

农民John每年有很多栅栏要修理。他总是骑着马穿过每一个栅栏并修复它破损的地方。John是一个与其他农民一样懒的人。他讨厌骑马,因此从来不两次经过一个栅栏。你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次。John能从任何一个顶点(即两个栅栏的交点)开始骑马,在任意一个顶点结束。每一个栅栏连接两个顶点,顶点用 1 1 1 500 500 500标号(虽然有的农场并没有 500 500 500个顶点)。一个顶点上可连接任意多( ≥ 1 ≥1 1)个栅栏。所有栅栏都是连通的(也就是你可以从任意一个栅栏到达另外的所有栅栏)。你的程序必须输出骑马的路径(用路上依次经过的顶点号码表示)。我们如果把输出的路径看成是一个 500 500 500进制的数,那么当存在多组解的情况下,输出 500 500 500进制表示法中最小的一个(也就是输出第一个数较小的,如果还有多组解,输出第二个数较小的,等等)。输入数据保证至少有一个解。

输入格式:
1 1 1行:一个整数 F F F,表示栅栏的数目;第 2 2 2 F + 1 F+1 F+1行:每行两个整数 i , j i,j i,j表示这条栅栏连接 i i i j j j号顶点。

输出格式:
输出应当有 F + 1 F+1 F+1行,每行一个整数,依次表示路径经过的顶点号。注意数据可能有多组解,但是只有上面题目要求的那一组解是认为正确的。

数据范围:
1 ≤ F ≤ 1024 1≤F≤1024 1F1024
1 ≤ i , j ≤ 500 1≤i,j≤500 1i,j500

相当于求一个欧拉路径,具体算法参考https://blog.csdn.net/qq_46105170/article/details/115060171。题目要求输出字典序最小的路径,只需在DFS的时候,每次都选取编号尽量小的顶点的那条边去走,最后将路径反序即可。注意DFS的时候仍然要做后序遍历,即回溯之前再将顶点加入路径。

有一个细节需要注意。出发点的选取方面,首先一定要选有邻边的点,在此情况下,再找度是奇数的顶点(如果原图不存在欧拉回路,但存在欧拉路,那么出发点和终点是唯二的度为奇数的顶点,选择其一为出发点即可),如果找不到度为奇数的点,那就从任意点出发都可以。

代码如下:

#include <iostream>
using namespace std;

const int N = 510, M = 1050;
int n, m;
// 可以用邻接矩阵存图,这样可以方便的按照从小到大的顺序遍历邻边,
// 其中g[i][j]表示从i到j的边有多少个
int g[N][N];
int res[M], cnt;
// d存每个顶点的度
int d[N];

void dfs(int u) {
    
    
	// 从小到大遍历邻接点
    for (int i = 1; i <= n; i++)
        if (g[u][i]) {
    
    
            g[u][i]--, g[i][u]--;
            dfs(i);
        }

    res[++cnt] = u;
}

int main() {
    
    
    cin >> m;
    for (int i = 0; i < m; i++) {
    
    
        int a, b;
        cin >> a >> b;
        g[a][b]++, g[b][a]++;
        d[a]++, d[b]++;
        n = max(n, max(a, b));
    }

    int s = 1;
    // 先找到非孤立点
    while (!d[s]) s++;
    // 再找度为奇数的点,如果找到了,则赋给s;如果找不到,那么s也可以作为DFS的起点
    for (int i = 1; i <= n; i++) 
        if (d[i] % 2) {
    
    
            s = i;
            break;
        }

    dfs(s);
	
	// 逆序输出路径
    for (int i = cnt; i; i--) cout << res[i] << endl;

    return 0;
}

时间复杂度 O ( F ) O(F) O(F),空间 O ( n 2 + F ) O(n^2+F) O(n2+F) n n n是顶点个数。

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/115107702