zoukankan      html  css  js  c++  java
  • UOJ 117 欧拉回路(套圈法+欧拉回路路径输出+骚操作)

    题目链接:http://uoj.ac/problem/117

    题目大意:

    解题思路:先判断度数:

         若G为有向图,欧拉回路的点的出度等于入度。

         若G为无向图,欧拉回路的点的度数位偶数。

         然后判断连通性,并且输出路径需要用套圈法(其实我也不是很懂)。

         还学了一些骚操作:

         ①用链式前向星存图,如果是有向图,那idx隔两个存一条边,如果是无向图则idx隔一个存一条边,且idx从2开始。这样写的作用就是在寻无向图路径时可以良好地标记,比如第一条无向边里idx=2、3分别对应一条正反边,2和3除2都对应1,那么我们只需标记vis[1]就好了,因为欧拉回路只需要用到其中一条边。有向图因为要防止两条当一条用,所以要idx要隔2存一条边。

         ②在遍历邻接表时j加一个引用,快了超多。

    代码:

     1 #include<iostream>
     2 #include<stack>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=1e5+5;
     8 const int M=2e5+5;
     9 
    10 struct node{
    11     int to,next,w;
    12 }edge[M*2];
    13 
    14 int n,m,idx,cnt;
    15 int head[N],in_deg[N],out_deg[N],ans[N];
    16 bool vis[M*2];
    17 
    18 void init(){
    19     idx=2;
    20     memset(vis,false,sizeof(vis));
    21     memset(head,0,sizeof(head));
    22     memset(in_deg,0,sizeof(in_deg));
    23     memset(out_deg,0,sizeof(out_deg));
    24 }
    25 
    26 void addedge(int u,int v,int w){
    27     edge[idx].to=v;
    28     edge[idx].next=head[u];
    29     edge[idx].w=w;
    30     head[u]=idx++;
    31 }
    32 
    33 //传说中的套圈法,输出欧拉回路路径
    34 void dfs(int u){
    35     //这个引用好神奇啊,速度快了好多,学习了0 0
    36     //好像类似于网络流的cur优化(没学过网路流,瞎说的)
    37     //然后关于idx的处理也很巧妙
    38     for(int &j=head[u];j;j=edge[j].next){
    39         node t=edge[j];
    40         if(!vis[j>>1]){
    41             vis[j>>1]=true;
    42             dfs(t.to);
    43             ans[++cnt]=t.w;
    44         }
    45     }
    46 }
    47 
    48 int main(){
    49     int t;
    50     scanf("%d%d%d",&t,&n,&m);
    51     init();
    52     int a,b;
    53     for(int i=1;i<=m;i++){
    54         scanf("%d%d",&a,&b);
    55         addedge(a,b,i);
    56         in_deg[b]++;
    57         out_deg[a]++;
    58         if(t==1)
    59             addedge(b,a,-i);
    60         else
    61             idx++;
    62     }
    63     bool flag=true;
    64     if(t==1){
    65         for(int i=1;i<=n;i++){
    66             if((in_deg[i]+out_deg[i])%2){
    67                 flag=false;
    68                 break;
    69             }
    70         }
    71     }
    72     else{
    73         for(int i=1;i<=n;i++){
    74             if(in_deg[i]!=out_deg[i]){
    75                 flag=false;
    76                 break;
    77             }
    78         }
    79     }
    80     if(flag){
    81         dfs(a);
    82         if(cnt!=m)
    83             puts("NO");
    84         else{
    85             puts("YES");
    86             for(int i=cnt;i>=1;i--){
    87                 if(i==1)
    88                     printf("%d
    ",ans[i]);
    89                 else
    90                     printf("%d ",ans[i]);
    91             }
    92         }
    93     }
    94     else
    95         puts("NO");
    96     return 0;
    97 }
  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/fu3638/p/7912579.html
Copyright © 2011-2022 走看看