P6066
[USACO05JAN]Watchcow S
POJ2230 。
然后这个就非常的巧妙。
我们知道 Hierholzer 算法中针对无向图要把无向图的无向边标记。
那么这个题要求正反各走一边,其实我们本来建的无向边就是两条有向边的拼凑,那干脆在标记的时候只标一个方向就解决了。
时间复杂度仍然是
然后数组好像要开大一点。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const ll N=1e5,M=5e5;
ll n,m,tot,top,t,u,v;
ll stk[M+5],ans[M+5];
ll ver[M*2+5],nxt[M*2+5],head[N+5];
bool vis[M*2+5];
void euler() {
stk[++top]=1;
while(top>0) {
ll x=stk[top],i=head[x];
while(vis[i]&&i) i=nxt[i];
if(i) {
stk[++top]=ver[i];
vis[i]=1;
head[x]=nxt[i];
}
else {
top--;ans[++t]=x;
}
}
}
void add(ll u,ll v) {
ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;
}
inline ll read() {
ll ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9') {ret=(ret<<3)+(ret<<1)+ch-'0';ch=getchar();}
return ret*f;
}
void write(ll x) {
if(x<0) {x=-x;putchar('-');}
ll y=10,len=1;
while(y<=x) {y*=10;len++;}
while(len--) {y/=10;putchar(x/y+48);x%=y;}
}
int main() {
n=read();m=read();
for(ll i=1;i<=m;i++) {
u=read();v=read();
add(u,v);add(v,u);
}
euler();
for(ll i=t;i;i--) printf("%lld\n",ans[i]);
return 0;
}