P2731 [USACO3.3]骑马修栅栏 Riding the Fences 欧拉回路 缩索

P2731 [USACO3.3]骑马修栅栏 Riding the Fences 欧拉回路 缩索

题目链接

​ 首先要想每个边都走一次, 必须是所有点都是偶点或者只有两个奇点.

​ 然后我们找到那个编号最小的奇点或偶点开始走, 贪心的选取下一条边, 直到不能走为止.

​ 注意统计路径的时候必须倒着统计, 正着统计会出大问题.比如样例:

\(5 \ 1 \ 2 \ \ 2 \ 3 \ \ 2 \ 4 \ \ 2 \ 5 \ \ 4 \ 5\).倒着统计答案应该是3 2 5 4 2 1, 而正着统计就会变成1 2 3 4 5 2

#include <bits/stdc++.h>

using namespace std;

inline long long read() {
	long long s = 0, f = 1; char ch;
	while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
	for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
	return s * f;
}

const int N = 1025;
int m, s, cnt, a[N][N], deg[N], road[N * 10];

int find(int x) {
	for(int i = 1;i < N; i++) if(a[x][i]) { a[x][i] --; a[i][x] --; find(i); }
	road[++ cnt] = x;
}

int main() {

	m = read();
	for(int i = 1, x, y;i <= m; i++) 
		x = read(), y = read(), a[x][y] ++, a[y][x] ++, deg[x] ++, deg[y] ++;
	s = 1;
	for(int i = 1;i < N; i++) if(deg[i] & 1) { s = i; break; }
	find(s);
	for(int i = cnt;i >= 1; i--) printf("%d\n", road[i]);

	return 0;
}
posted @ 2020-11-13 06:34  C锥  阅读(83)  评论(0编辑  收藏  举报