zoukankan      html  css  js  c++  java
  • 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
    ");return 0;}
      if(cnt==2&&jd==4&&col[q[1]]==col[q[2]]==col[q[3]]==col[q[4]]){printf("-1
    ");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
    %d
    ",sta[top]);
          printf("%d
    ",ct1-1);
          for(int i=top-1;i;i--)printf("%d ",sta[i]);
          return 0;
        }
      printf("%d
    ",ct1);
      for(int i=ct1;i;i--)
          printf("%d ",sta[i]);
      printf("
    ");
      printf("%d
    ",top-ct1);
      for(int i=top;i>ct1;i--)
        printf("%d ",sta[i]);
      return 0;
    }
  • 相关阅读:
    动态设置字体大小需要注意的点
    getDimension与getDimensionPixelOffset与getDimensionPixelSize的区别
    统计图钻取的明细报表在非模态窗口中显示
    局部区块多个报表 TAB 页切换及局部区块的参数查询
    分栏报表制作攻略
    多值关联过滤
    鼠标悬停出现提示信息怎么做
    复杂报表设计之动态报表
    Logo(图片)作为报表水印的解决方法
    分组填报表的制作
  • 原文地址:https://www.cnblogs.com/Narh/p/9279335.html
Copyright © 2011-2022 走看看