题意:
无向图求一条敲好经过所有边正反两次的回路。
分析:
无向图求欧拉回路时走过一条边后要把两点之间的两条方向相反的边均标记,
这题可以看做一张有向图中求欧拉回路,所以每次只标记一条边就可以了。
AC代码:(注意手写栈的数据范围)
#include<iostream>
#define ll long long
using namespace std;
const int N=10010;
const int M=50010*2;
int head[N];
int ver[M];
int Next[M];
int n,m,tot;
void add(int x,int y)
{
ver[++tot]=y;
Next[tot]=head[x];
head[x]=tot;
}
int stackk[M],ans[M];//注意模拟栈的数据范围
bool vis[M];//vis标记的边
int top,t;//模拟栈“指针”,答案数组个数
void eular()
{
stackk[++top]=1;
while(top>0)
{
int x=stackk[top],i=head[x];
while(i&&vis[i])i=Next[i];
if(i)
{
stackk[++top]=ver[i];
vis[i]=true;//无向图时:vis[i]=vis[i^1]=true;
head[x]=Next[i];
}
else
{
top--;
ans[++t]=x;
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
tot=1;
t=0;
top=0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(Next,0,sizeof(Next));
memset(ver,0,sizeof(ver));
for(int i=1;i<=m;++i)
{
int x,y;
cin>>x>>y;
add(x,y);
add(y,x);
}
eular();
for(int i=t;i>0;i--)printf("%d\n",ans[i]);
}
return 0;
}
The end;