POJ 2230 Watchcow 尤拉回路

~hsm~發表於2019-03-09

title

POJ 2230
CH POJ2230

analysis

我們只需要在求尤拉回路的參考程式中,去掉對每條邊的vis標記,即可得到本題的解答。
這是因為,按照一般的儲存方式,每條無向邊在鄰接表中會以正、反兩個方向分別儲存一次。
若沒有vis標記,則根據表頭陣列head的更新方式,每條無向邊會被正、反各經過一次,恰好滿足題目要求。
這是《算階》上的原題解。

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1,ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}
int ver[maxn<<1],Next[maxn<<1],head[maxn],len;
inline void add(int x,int y)
{
	ver[++len]=y,Next[len]=head[x],head[x]=len;
}
int Stack[maxn],top;
int ans[maxn],t;
bool vis[maxn];
inline void eular()
{
	Stack[++top]=1;
	while (top>0)
	{
		int x=Stack[top],i=head[x];
		while (i && vis[i]) i=Next[i];
		if (i)
		{
			Stack[++top]=ver[i];
//			vis[i]=vis[i^1]=1;
			head[x]=Next[i];
		}
		else
		{
			--top;
			ans[++t]=x;
		}
	}
}
int main()
{
	int n,m;
	read(n);read(m);
	len=1;
	for (int i=1;i<=m;++i)
	{
		int x,y;
		read(x);read(y);
		add(x,y);add(y,x);
	}
	eular();
	for (int i=t;i;--i)
		printf("%d\n",ans[i]);
	return 0;
}