【USACO 3.3】Riding The Fences(欧拉路径)

题意:

给你每个fence连接的两个点的编号,输出编号序列的字典序最小的路径,满足每个fence必须走且最多走一次。

题解:

本题就是输出欧拉路径。
题目保证给出的图是一定存在欧拉路径,因此找到最小的度数为奇数的点(要么有两个,要么没有)出发,如果没有,就从最小的点出发。
然后用fleury算法。
fleury算法其实就是dfs,每次走过的边就删去(做上标记)。
回溯的时候把点放入栈内。
最后全部出栈就是所求的路径。

代码:

/*
TASK:fence
LANG:C++
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define in(s) freopen(#s".in","r",stdin)
#define out(s) freopen(#s".out","w",stdout);
#define ll long long
#define N 501
using namespace std;
int g[N][N],maxn,minn=N;
int d[N];
int stack[N],top;
void dfs(int u){
	for(int v=1;v<=maxn;v++)if(g[u][v]){
		g[u][v]--;
		g[v][u]--;
		dfs(v);
	}
	stack[top++]=u;
}
int main() {
	in(fence);
	out(fence);
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u][v]++;
		g[v][u]++;
		d[u]++;d[v]++;
		maxn=max(max(maxn,u),v);
		minn=min(min(minn,u),v);
	}
	int i=1;
	while(i<N&&d[i]%2==0)i++;
	if(i<N)dfs(i);//找到第一个度数是奇数的点,则从这个点出发
	else dfs(minn);//否则从最小的出现的点出发
	while(top--)printf("%d
",stack[top]);
	return 0;
}
原文地址:https://www.cnblogs.com/flipped/p/6252818.html