zoukankan      html  css  js  c++  java
  • 欧拉回路 uoj117

    写了一道欧拉回路的模板题。先判断是否是欧拉回路,有向图和无向图有一点点不同,然后就是特判独立点的存在。

    之后是输出路径,和dls学的dfs,利用last数组的更新可以做到线性的复杂度,否则一不小心就会写成m^2的复杂度

    附上代码——by VANE

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 int t,n,m;
      4 const int N=100005;
      5 int l,last[N],pre[N<<2],other[N<<2],f[N];
      6 int rd[N],cd[N];
      7 int getfa(int x)
      8 {
      9     return x==f[x]?x:f[x]=getfa(f[x]);
     10 }
     11 bool not_lone[N];
     12 bool vis[N<<2];
     13 void add(int a,int b,int c)
     14 {
     15     if(c==1)
     16     {++l;pre[l]=last[a];last[a]=l;other[l]=b;}
     17     else 
     18     {int L=l+m;pre[L]=last[a];last[a]=L;other[L]=b;}
     19 }
     20 void merge(int x,int y)
     21 {
     22     int fx=getfa(x),fy=getfa(y);
     23     if(fx!=fy)
     24     f[fx]=fy;
     25 }
     26 int abs(int x)
     27 {
     28     return x<=m?x:x-m;
     29 }
     30 int val(int x)
     31 {
     32     return x<=m?x:m-x;
     33 }
     34 stack<int> sk;
     35 void dfs(int x)
     36 {
     37     for(int p=last[x];p;p=last[x])
     38     {
     39         while(vis[abs(p)]&&p) p=pre[p];
     40         last[x]=p;
     41         if(p)
     42         {    
     43             vis[abs(p)]=1;
     44             dfs(other[p]);    
     45             sk.push(val(p));
     46         }
     47     }
     48 
     49 }
     50 int main()
     51 {
     52     scanf("%d%d%d",&t,&n,&m);
     53     for(int i=1;i<=n;++i) f[i]=i;
     54     for(int i=1;i<=m;++i)
     55     {
     56         int x,y;scanf("%d%d",&x,&y);
     57         add(x,y,1);if(t==1) add(y,x,m);
     58         cd[x]++;rd[y]++;
     59         not_lone[x]=not_lone[y]=1;
     60         merge(x,y);
     61     }
     62     int rt=0;
     63     for(int i=1;i<=n;++i)
     64     {
     65         if(not_lone[i])
     66         {
     67             rt=i;break;
     68         }
     69     }
     70     for(int i=1;i<=n;++i)
     71     if(not_lone[i]&&getfa(i)!=getfa(rt))
     72     {
     73         puts("NO");
     74         return 0;
     75     }
     76     if(t==1)
     77     {
     78         for(int i=1;i<=n;++i)
     79         if((rd[i]+cd[i])&1)
     80         {puts("NO");return 0;}
     81     }
     82     else
     83     {
     84         for(int i=1;i<=n;++i)
     85         if(rd[i]!=cd[i])
     86         {puts("NO");return 0;}
     87     }
     88     for(int i=1;i<=n;++i)
     89     if(not_lone[i])
     90     {
     91         dfs(i);
     92         break;
     93     }
     94     puts("YES");
     95     while(!sk.empty())
     96     {
     97         printf("%d ",sk.top());
     98         sk.pop();
     99     }
    100 }

    下面的By:大奕哥

    我们就直接搜索啦,对于无向图需要保证的性质是任何点的出度+入度都要为偶数,对于有向图任意点的出度都要等于入度。

    搜索就是一个回溯的过程,然后每次我们都把边删掉(head[x]=i)

    然后如果要是能搜的话我们就加入队列。

    在这里要特别注意对于孤立点(无任何边连入无任何边连出)的点,搜索从任意一个连边的点即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=500005;
     4 int n,m,top,cnt,f[N],head[N],d1[N],d2[N],q[N];
     5 struct node
     6 {
     7     int to,nex,w;
     8 }e[N<<1];
     9 void add(int x,int y,int w)
    10 {
    11     e[++cnt].to=y;e[cnt].nex=head[x];
    12     head[x]=cnt;e[cnt].w=w;
    13     d1[x]++;d2[y]++;
    14 }
    15 void dfs(int x)
    16 {
    17     for(int i=head[x];i;i=head[x])
    18     {
    19         while(i&&f[abs(e[i].w)])i=e[i].nex;
    20         head[x]=i;
    21         if(i)
    22         {
    23             f[abs(e[i].w)]=1;
    24             dfs(e[i].to);
    25             q[++top]=e[i].w;
    26         }
    27     }
    28 }
    29 int main()
    30 {
    31     int n,m,x,y,p,k;
    32     scanf("%d%d%d",&p,&n,&m);
    33     for(int i=1;i<=m;++i)
    34     {
    35         scanf("%d%d",&x,&y);
    36         add(x,y,i);
    37         if(p==1)add(y,x,-i);
    38     }
    39     for(int i=1;i<=n;++i)if(p==1&&d1[i]%2||p==2&&d1[i]!=d2[i]){puts("NO");return 0;}
    40     dfs(x);
    41     if(top<m){puts("NO");return 0;}
    42     puts("YES");
    43     for(int i=top;i;--i)printf("%d ",q[i]);
    44     return 0;
    45 }
  • 相关阅读:
    docker 使用 记录
    vagrant up 网络问题
    PHPSTORM去除警告波浪线的方法
    vagrant共享目录出现“mount:unknown filesystem type ‘vboxsf‘”错误解决方法(亲测可行)
    SVN比较本地相对于上一版本的修改
    Mysql on duplicate key update用法及优缺点
    win10中PHPstorm 里面Terminal 不能使用 esc键吗退出编辑模式吗
    在docker 上安装lnmp 环境
    经典算法题每日演练——第九题 优先队列
    经典算法题每日演练——第十二题 线段树
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8028897.html
Copyright © 2011-2022 走看看