CF 36E Two Paths——欧拉路

题目:http://codeforces.com/contest/36/problem/E

找出两条欧拉路覆盖无向图。

套上欧拉路模板。用过的边要记录。

注意 一个连通块、4个奇度数点 的情况是在两个奇度数点之间连一条边,跑完欧拉路后再断开!而不是……

特别奇怪的一点是如果不写那个  跑完欧拉路后发现队列里的边不足m条就输出-1  就会WA。

  但Zinn没有这个特判,我也觉得这种情况很奇怪。可能是代码别的地方写错了?

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e4+5;
int n,m,mp[N],hd[N],xnt,deg[N],col[N],cnt;
int sta[N],top,q[N],jd,ct1;
bool use[N],vis[N];
struct Ed{
  int nxt,to,bh;Ed(int n=0,int t=0,int b=0):nxt(n),to(t),bh(b) {}
}ed[N<<1];
void add(int x,int y,int b)
{
  ed[++xnt]=Ed(hd[x],y,b);hd[x]=xnt;
  ed[++xnt]=Ed(hd[y],x,b);hd[y]=xnt;
}
void dfs(int cr)
{
  col[cr]=cnt;if(deg[cr]&1)q[++jd]=cr;
  for(int i=hd[cr];i;i=ed[i].nxt)
    if(!col[ed[i].to])dfs(ed[i].to);
}
void dfs(int rt,int cr,int fa)
{
  vis[cr]=1;
  for(int i=hd[cr];i;/*i=hd[cr]*/i=ed[i].nxt)
    if(!use[ed[i].bh])
      {
    //      hd[cr]=ed[i].nxt;//!
    use[ed[i].bh]=1;
    dfs(rt,ed[i].to,cr);
    sta[++top]=ed[i].bh;
    if(ed[i].bh==m+1)ct1=--top;
      }
}
int main()
{
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  scanf("%d",&m);int x,y;
  for(int i=1;i<=m;i++)
    {
      scanf("%d%d",&x,&y);
      if(!mp[x])mp[x]=++n;
      if(!mp[y])mp[y]=++n;
      deg[mp[x]]++;deg[mp[y]]++;
      add(mp[x],mp[y],i);
    }
  for(int i=1;i<=n;i++)
    if(!col[i])
      {
    cnt++;dfs(i);
      }
  if(cnt>2||jd>4||m==1){printf("-1\n");return 0;}
  if(cnt==2&&jd==4&&col[q[1]]==col[q[2]]==col[q[3]]==col[q[4]]){printf("-1\n");return 0;}
  memset(vis,0,sizeof vis);
  if(cnt==2)
  {
      if(jd)
    {
      dfs(q[1],q[1],0);ct1=top;
      if(jd==2)
    {
      for(int i=1;i<=n;i++)
        if(!vis[i]){dfs(i,i,0);break;}
    }
      else{
    for(int i=1;i<=4;i++)
      if(!vis[q[i]]){dfs(q[i],q[i],0);break;}
      }
    }
    else{
       dfs(1,1,0);ct1=top;
      for(int i=1;i<=n;i++)if(!vis[i]){dfs(i,i,0);break;}
    }
  }
  else{
      if(jd)
      {
      if(jd==4){
          add(q[3],q[4],m+1);dfs(q[1],q[1],0);/////////
      }
      else dfs(q[1],q[1],0),ct1=top;
      }
      else ct1=m,dfs(1,1,0);
  }
  if(top!=m){printf("-1");return 0;}///////?
  if(ct1==top)
    {
      printf("1\n%d\n",sta[top]);
      printf("%d\n",ct1-1);
      for(int i=top-1;i;i--)printf("%d ",sta[i]);
      return 0;
    }
  printf("%d\n",ct1);
  for(int i=ct1;i;i--)
      printf("%d ",sta[i]);
  printf("\n");
  printf("%d\n",top-ct1);
  for(int i=top;i>ct1;i--)
    printf("%d ",sta[i]);
  return 0;
}

 

posted on 2018-07-08 10:14  Narh  阅读(143)  评论(0编辑  收藏  举报

导航