欧拉问题
欧拉路径,如果一个图存在一个笔画,那么笔画的路径叫做欧拉路径,
欧拉回路,如果最后又可以回到起点,就叫欧拉回路
奇点是指一个点的相连的边的数目为奇数个的点,那么对于欧拉路径欧拉回路,肯定存在如下的定理:
1.欧拉路径,图必须连通,有且只有2个奇点
2.欧拉回路,图必须联通,有0个奇点
那么如何去求解一个欧拉问题呢?这里算法分两种:
Fleury
这个算法解决欧拉回路的具体输出路径,是一种依靠删边的方法求解
算法每次从栈中获取这个点,判断它是否孤立,也就是是否还有连边,如果是一个孤立的点就输出说明是一个欧拉序列,否则进行一个拓展,将这个点入栈然后将他的边全部删除,感觉和拓扑很像
void dfs(int now)
{//继续拓展
que[tot++]=now;
for(int i=1;i<=n;i++)
{
if(mp[x][i])
{
mp[x][i]=mp[i][x]=0;
dfs(i);
break;
}
}
}
void fleury(int now)
{
int flag=1;
que[tot++]=now;
while(tot)
{
flag=1;
for(int i=1;i<=n;i++)
if(mp[que[tot-1]][i])
{
flag=0;
break;
}
if(flag)
{
cout<<que[--tot];//无法进行拓展
}
else
{
dfs(que[--tot]);//进行拓展
}
}
}
Hierholzer
这个算法相当于简单好理解
其实也是一个删边算法,从一个奇点开始进行不断的进行删边运算,递归删除然后找到孤立 的点
void Hierholzer(int now)
{
for(int i=1;i<=n;i++)
{
if(mp[now][i])
{
mp[now][i]=mp[i][now]=0;
dfs(i);
}
}
answer[++ans]=now;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>x>>y;
mp[x][y]=mp[y][x]=1;
du[x++];du[y++];//统计度数
}
now=1;
for(int i=1;i<=n;i++)
{
if(du[i]&1)
{
now=i;
}
}
ans=0;
Hierholzer(now);
for(int i=1;i<=n;i++)
{
cout<<answer[i]<" ";
}
return 0;
}