zoukankan      html  css  js  c++  java
  • 【UOJ#177】欧拉回路

    题面

    http://uoj.ac/problem/117

    题解

    • 不能从$1$开始,因为$1$可能不和别的联通,随便选一个有边的点开始。
    • 注意当前弧优化(就是把已经用过的边删掉的过程),没有会超时。
    • 注意原图不连通的情况,$s.size()<m$,应该算无解。
    #include<stack>
    #include<vector>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 100050
    #define ri register int
    using namespace std;
    
    int t;
    int n,m,u,v;
    stack<int> s;
    int cur[N];
    int rd[N],cd[N],deg[N];
    vector<int> ed[N],vv,to;
    
    inline int read() {
      int ret=0,f=0; char ch=getchar();
      while (ch<'0' || ch>'9') f|=(ch=='-'),ch=getchar();
      while (ch>='0' && ch<='9') ret*=10,ret+=(ch-'0'),ch=getchar();
      return f?-ret:ret;
    }
    
    void add_edge(int u,int v) {
      to.push_back(v); vv.push_back(0); ed[u].push_back(to.size()-1);
      to.push_back(u); vv.push_back(0); ed[v].push_back(to.size()-1);
      deg[u]++; deg[v]++;
    }
    
    void add(int u,int v) {
      to.push_back(v); vv.push_back(0); ed[u].push_back(to.size()-1);
      rd[v]++; cd[u]++;
    }
    
    void euler1(int x) {
      for (ri &i=cur[x];i<ed[x].size();i++) {
        int e=ed[x][i];
        if (vv[e]) continue;
        vv[e]=vv[1^e]=1;
        euler1(to[e]);
        s.push((e&1)?-(e/2+1):e/2+1);
      }
    }
    
    void euler2(int x) {
      for (ri &i=cur[x];i<ed[x].size();i++) {
        int e=ed[x][i];
        if (vv[e]) continue;
        vv[e]=1;
        euler2(to[e]);
        s.push(e+1);
      }
    }
    
    int main(){
      t=read();
      n=read(); m=read();
      memset(cur,0,sizeof(cur));
      if (t==1) {
        for (ri i=1;i<=m;i++) {
          u=read(),v=read();
          add_edge(u,v);
        }
        for (ri i=1;i<=n;i++) if (deg[i]&1) {
          puts("NO");
          return 0;
        }
        euler1(u);
        if (s.size()<m) {
          puts("NO");
          return 0;
        }
        puts("YES");
        while (!s.empty()) printf("%d ",s.top()),s.pop();
      }
      else {
        for (ri i=1;i<=m;i++) {
          u=read(),v=read();
          add(u,v);
        }
        for (ri i=1;i<=n;i++) if (rd[i]^cd[i]) {
          puts("NO");
          return 0;
        }
        euler2(u);
        if (s.size()<m) {
          puts("NO");
          return 0;
        }
        puts("YES");
        while (!s.empty()) printf("%d ",s.top()),s.pop();
      }
      return 0;
    }
  • 相关阅读:
    STR[#6]
    整数
    一些应该记住的东西(持续更新?再也不会更新了)
    退役后的续命杂谈
    51Nod 快速傅里叶变换题集选刷
    支配树学习笔记
    动态点分治入门随讲
    KD树小结
    HNOI2013 BZOJ3142 数列
    BZOJ2001 HNOI2010 城市建设
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11324785.html
Copyright © 2011-2022 走看看