#欧拉回路#HDU 5348 MZL's endless loop
题目
给无向图定向,使每个点的入度与出度之差绝对值不超过一。
分析
考虑沿欧拉回路方向定向后的入度与出度之差为 \(0\),而欧拉回路可以是全为偶点的无向图,
所以对于奇点直接连虚拟边就能使其不超过一,对于每个连通分支分别使用 Hierholzer 算法找出欧拉回路并定向。
注意:一定要使用当前弧优化,不然会 TLE。
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100011;
struct node{int y,next;}e[N<<3];
int v[N],as[N],mark[N<<3],deg[N],n,m,et;
int iut(){
int ans=0,f=1; char c=getchar();
while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans*f;
}
void dfs(int x){
v[x]=1;
for (int &i=as[x];i;i=e[i].next)
if (mark[i]==-1){
mark[i]=1,mark[i^1]=0;
dfs(e[i].y);
}
}
int main(){
memset(mark,0xff,sizeof(mark));
for (int T=iut();T;--T){
n=iut(),m=iut(),et=1;
for (int i=1;i<=m;++i){
int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et,++deg[x];
e[++et]=(node){x,as[y]},as[y]=et,++deg[y];
}
for (int i=1,lst=0;i<=n;++i)
if (deg[i]&1){
if (lst){
e[++et]=(node){i,as[lst]},as[lst]=et;
e[++et]=(node){lst,as[i]},as[i]=et;
lst=0;
}else lst=i;
}
for (int i=1;i<=n;++i) if (!v[i]) dfs(i);
for (int i=1;i<=m;++i) putchar(mark[i<<1]+48),putchar(10);
for (int i=1;i<=n;++i) deg[i]=as[i]=v[i]=0;
for (int i=2;i<=et;++i) mark[i]=-1;
}
return 0;
}