递归欧拉路模板。当前弧优化。

#include<bits/stdc++.h>
#define F(i,a,b) for(int i=a;i<=b;++i)
#define LL long long
#define pf(a) printf("%d ",a)
#define phn puts("")
using namespace std;
int read();
/** 当前弧优化,否则会卡成m^2. 没有固定起点时可以随便选,但必须有边与他相连,不能直接用1.*/
#define N 400010 
int T,n,m;
int chu[N],ru[N],du[N],to[N<<1],fir[N<<1],id[N<<1],head[N],cnt;
void add(int x,int y,int ID){to[++cnt]=y;fir[cnt]=head[x];head[x]=cnt;id[cnt]=ID;}
int sta[N<<1],vis[N<<1],top;
void dfs1(int x){
    for(int i=head[x];i;){
        while(i&&vis[i])i=fir[i];
        if(i){
            vis[i]=1;head[x]=fir[i];
            dfs1(to[i]);
            sta[++top]=id[i];
            i=head[x];
        }
    }
}    
void dfs2(int x){
    for(int i=head[x];i;){
        while(i&&vis[i]&&vis[i^1])i=fir[i];
        if(i){
            vis[i]=vis[i^1]=1;head[x]=fir[i];
            dfs2(to[i]);
            sta[++top]=id[i];
            i=head[x];
        }
    }
}
void work1(){//不交换,单向
    cnt=0;
    for(int i=1,u,v;i<=m;++i){
        u=read();v=read();
        add(u,v,i);++chu[u];++ru[v];
    }
    int s=to[2],x=0,y=0;
    F(i,1,n){
        if(chu[i]-ru[i]==1)++x,s=i;
        else if(ru[i]-chu[i]==1)++y;
        else if(chu[i]!=ru[i]){
            puts("NO");exit(0);
        }
    }
    if((!x&&!y)||(x==1&&y==1));
    else {puts("NO"),exit(0);}
    dfs1(s);
    F(i,1,m){
        if(!vis[i]){puts("NO"),exit(0);}
    }
    puts("YES");
    for(int i=top;i>0;--i)pf(sta[i]);phn;
/*    memset(vis,0,sizeof(vis));
    for(int i=top;i>0;--i){
        s=to[i];vis[i]=1;
    }
    F(i,1,m)if(!vis[i])puts("WA");
    puts("Nicer");*/
}    
void work2(){//交换,双向
    cnt=1;
    for(int i=1,u,v;i<=m;++i){
        u=read();v=read();
        add(u,v,i);add(v,u,-i);
        ++du[u];++du[v];
    }
    int s=to[2],x=0;
    F(i,1,n){
        if(du[i]&1)++x,s=i;
    }
    if(x==2||!x);
    else {puts("NO"),exit(0);}
    dfs2(s);
    F(i,1,m){
        if(!vis[i<<1]||!vis[i<<1|1]){puts("NO"),exit(0);}
    }
    puts("YES");
    for(int i=top;i>0;--i)pf(sta[i]);phn;    
}
int main(){
    freopen("merge.in","r",stdin);freopen("merge.out","w",stdout);
/** *///    freopen("ex_merge4.in","r",stdin);//freopen("merge.out","w",stdout);
    T=read();n=read();m=read();
    if(T==2)work1();
    else if(T==1)work2();
}
int read(){
    int s=0,f=0;char ch=getchar();
    while(!isdigit(ch))f=ch=='-',ch=getchar();
    while(isdigit(ch))s=s*10+(ch^48),ch=getchar();
    return f?-s:s;
}
/*
g++ dp.cpp
./a.out
g++ merge.cpp -std=c++11 
./a.out
2 5 5
2 3
2 5
3 4
1 2
4 2
*/
测试100T1

对于本题:当前弧优化,否则会卡成m^2. 没有固定起点时可以随便选,但必须有边与他相连,不能直接用1.

加当前弧后是n+m,否则可以卡成m^2.(两个点直接连m条边)

posted @ 2019-11-04 19:33  seamtn  阅读(214)  评论(0编辑  收藏  举报