#欧拉回路#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;
}
posted @ 2024-10-28 19:58  lemondinosaur  阅读(5)  评论(0编辑  收藏  举报