zoukankan      html  css  js  c++  java
  • [UOJ117] 欧拉回路

    描述

    有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。

    一共两个子任务:

    1. 这张图是无向图。(50分)
    2. 这张图是有向图。(50分)

    输入格式

    第一行一个整数 tt,表示子任务编号。t{1,2}t∈{1,2},如果 t=1t=1 则表示处理无向图的情况,如果 t=2t=2 则表示处理有向图的情况。

    第二行两个整数 n,mn,m,表示图的结点数和边数。

    接下来 mm 行中,第 ii 行两个整数 vi,uivi,ui,表示第 ii 条边(从 11 开始编号)。保证 1vi,uin1≤vi,ui≤n。

    1. 如果 t=1t=1 则表示 vivi 到 uiui 有一条无向边。
    2. 如果 t=2t=2 则表示 vivi 到 uiui 有一条有向边。

    图中可能有重边也可能有自环。

    输出格式

    如果不可以一笔画,输出一行 “NO”。

    否则,输出一行 “YES”,接下来一行输出一组方案。

    1. 如果 t=1t=1,输出 mm 个整数 p1,p2,,pmp1,p2,…,pm。令 e=pie=∣pi∣,那么 ee 表示经过的第 ii 条边的编号。如果 pipi 为正数表示从 veve 走到 ueue,否则表示从 ueue 走到 veve。
    2. 如果 t=2t=2,输出 mm 个整数 p1,p2,,pmp1,p2,…,pm。其中 pipi 表示经过的第 ii 条边的编号。

    样例一

    input

    1
    3 3
    1 2
    2 3
    1 3
    
    

    output

    YES
    1 2 -3
    
    

    样例二

    input

    2
    5 6
    2 3
    2 5
    3 4
    1 2
    4 2
    5 1
    
    

    output

    YES
    4 1 3 5 2 6
    
    

    限制与约定 1≤n≤105,0≤m≤2×105

    时间限制1s1s

    空间限制:256MB

    思路

    圈套法(弗洛莱算法)

    代码实现

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 #define maxn 100010
     5 #define maxm 400010
     6 struct edge{
     7     int v;
     8     bool ban;
     9     edge *nxt;
    10 }ep[maxm];
    11 int t,n,m,ecnt,cnt,ind[maxn],outd[maxn],ans[maxm];
    12 edge *g[maxn];
    13 inline void addedge(int u,int v){
    14     edge *p=&ep[ecnt++];
    15     p->v=v; p->ban=false; p->nxt=g[u];
    16     g[u]=p;
    17 }
    18 inline edge* rev(edge *j){
    19     int i=j-ep;
    20     return ep+(i^1);
    21 }
    22 void dfs_ud(int i){
    23     while (g[i])
    24         if (!g[i]->ban){
    25             edge *j=g[i];
    26             j->ban=true;
    27             rev(j)->ban=true;
    28             dfs_ud(j->v);
    29             int tmp=j-ep;
    30             if(tmp&1) tmp=-(tmp/2+1);
    31             else tmp=tmp/2+1;
    32             ans[cnt++]=tmp;
    33         }
    34         else g[i]=g[i]->nxt;
    35 }
    36 void dfs_d(int i){
    37     while (g[i])
    38         if (!g[i]->ban){
    39             edge *j=g[i];
    40             j->ban=true;
    41             dfs_d(j->v);
    42             ans[cnt++]=j-ep+1;
    43         }
    44         else g[i]=g[i]->nxt;
    45 }
    46 int main(){
    47     scanf("%d%d%d",&t,&n,&m);
    48     ecnt=0;
    49     memset(g,0,sizeof(g));
    50     memset(ind,0,sizeof(ind));
    51     memset(outd,0,sizeof(outd));
    52     for (int i=0;i<m;++i){
    53         int u,v;
    54         scanf("%d%d",&u,&v);
    55         --u,--v;
    56         addedge(u,v);
    57         ++outd[u];++ind[v];
    58         if (t==1) addedge(v,u),++outd[v],++ind[u];
    59     }
    60     cnt=0;
    61     if (t==1){
    62         bool flag=true;
    63         for (int i=0;i<n;++i)
    64             if(ind[i]&1){flag=false;break;}
    65         if(!flag) puts("NO");
    66         else{
    67             for(int i=0;i<n;++i){
    68                 dfs_ud(i);
    69                 if (cnt) break;
    70             }
    71             if (cnt==m){
    72                 puts("YES");
    73                 for (int i=cnt-1; i>=0; --i) printf("%d ",ans[i]);
    74                 puts("");
    75             }
    76             else puts("NO");
    77         }
    78     }
    79     else{
    80         edge *p=g[0];
    81         while (p) p=p->nxt;
    82         bool flag=true;
    83         for(int i=0;i<n;++i) if(ind[i]!=outd[i]){flag=false;break;}
    84         if (!flag) puts("NO");
    85         else{
    86             for(int i=0;i<n;++i){
    87             dfs_d(i);
    88             if(cnt) break;
    89             }
    90             if(cnt==m){
    91                 puts("YES");
    92                 for(int i=cnt-1;i>=0;--i) printf("%d ",ans[i]);
    93                 puts("");
    94             }
    95             else puts("NO");
    96         }
    97     }
    98     return 0;
    99 }

    手动copy的代码,根本看不懂大佬在干嘛呀。

    56MB

  • 相关阅读:
    Algorithm Gossip (48) 上三角、下三角、对称矩阵
    .Algorithm Gossip (47) 多维矩阵转一维矩阵
    Algorithm Gossip (46) 稀疏矩阵存储
    Algorithm Gossip (45) 费氏搜寻法
    Algorithm Gossip (44) 插补搜寻法
    Algorithm Gossip (43) 二分搜寻法
    Algorithm Gossip (42) 循序搜寻法(使用卫兵)
    Algorithm Gossip (41) 基数排序法
    Algorithm Gossip (40) 合并排序法
    AlgorithmGossip (39) 快速排序法 ( 三 )
  • 原文地址:https://www.cnblogs.com/J-william/p/7045492.html
Copyright © 2011-2022 走看看