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

    试题描述
    有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
    一共两个子任务:
    这张图是无向图。
    这张图是有向图。
    输入
    第一行一个整数 t,表示子任务编号。t∈{1,2},如果 t=1 则表示处理无向图的情况,如果 t=2 则表示处理有向图的情况。
    第二行两个整数 n,m,表示图的结点数和边数。
    接下来 m 行中,第 i 行两个整数 vi,ui​​ ,表示第 i 条边(从 1 开始编号)。保证 1≤vi,ui≤n。
    如果 t=1 则表示 vi​  到 ui​​  有一条无向边。
    如果 t=2则表示 vi有一条有向边。
    图中可能有重边也可能有自环。
    输出
    如果不可以一笔画,输出一行 NO。
    否则,输出一行 YES,接下来一行输出一组方案。
    如果 t=1,输出 m 个整数 
    p1,p2,…,pm。令 e=∣pi∣,那么 e 表示经过的第 i 条边的编号。如果 pi为正数表示从 ve走到 ue,否则表示从 ue走到 ve。
    如果 t=2,输出 m 个整数 p1,p2,…,pm。其中 pi表示经过的第 i 条边的编号。
    输入示例
    样例输入 1
    1
    3 3
    1 2
    2 3
    1 3
    样例输入 2
    2
    5 6
    2 3
    2 5
    3 4
    1 2
    4 2
    5 1
    输出示例
    样例输出 1
    YES
    1 2 -3
    样例输出 2
    YES
    4 1 3 5 2 6
    其他说明
    数据范围与提示
    1≤n≤10^5,0≤m≤2×10^5

    欧拉回路的模板,两种都包含了

    首先是特判,关系到欧拉回路的定义

    对于无向图,每个点的度都要为偶数

    对于有向图,每个点的入度要和出度相等

    然后是DFS判环,记录每条边是否走过,对于无相变要加一个特判

    因为无向图的邻接表会连两条,而编号只有从1到m

    而我们又知道,从左到右的边的编号是奇数,反之则是偶数

    所以只需要进行奇偶的判断,然后将反向的边也染色

    最后输出的时候也要特判,无向图要把编号除2,然后判断正负(根据题意)

    下面给出代码:

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    using namespace std;
    inline int rd(){
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void write(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    int f,n,m;
    int head[200006],nxt[400006],to[400006];
    int total=0;
    void add(int x,int y){
        total++;
        to[total]=y;
        nxt[total]=head[x];
        head[x]=total;
        return ;
    }
    int du[200006],in[200006],out[200006];
    int tot=0;
    int vis[400006];
    int ans[400006];
    void dfs(int x){
        for(int &e=head[x];e;e=nxt[e]){
            if(!vis[e]){
                int k=e;
                vis[e]=1;
                if(f==1){
                    if(e%2) vis[e+1]=1;
                    else vis[e-1]=1;
                }
                dfs(to[e]);
                ans[++tot]=k;
            }
        }
        return ;
    }
    int main(){
        f=rd(),n=rd(),m=rd();
        for(int i=1;i<=m;i++){
            int x=rd(),y=rd();
            add(x,y);
            in[y]++,out[x]++;
            if(f==1) add(y,x),du[x]++,du[y]++;
        }
        if(f==1) for(int i=1;i<=n;i++) if(du[i]%2){
            printf("NO");
            return 0;
        }
        if(f==2) for(int i=1;i<=n;i++) if(out[i]!=in[i]){
            printf("NO");
            return 0;
        }
        for(int i=1;i<=n;i++) if(head[i]){
            dfs(i);
            break;
        }
        if(tot!=m){
            printf("NO");
            return 0;
        }
        puts("YES");
        if(f==2) for(int i=tot;i>=1;i--) write(ans[i]),printf(" ");
        if(f==1) for(int i=tot;i>=1;i--){
            if(ans[i]%2) write((ans[i]+1)/2),printf(" ");
            else write(ans[i]/(-2)),printf(" ");
        }
        return 0;
    }
    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    ios的自动转屏
    Acoustic Echo Cancellation (AEC) 回音消除技术探索
    springMVC之数据传递
    redis.conf 配置详解
    HDU 1880 字符串hash 入门题
    算法题: 求一个整数数组中,通过元素加减运算得到指定结果的所有运算过程. 例如【5,4,6,7,1】= 9 ?
    创建和使用SQL Server SSAS本地多维数据集
    yum局域网软件源搭建
    [置顶] 使用Android OpenGL ES 2.0绘图之六:响应触摸事件
    [置顶] Nosql笔记(一)——关系型数据库回顾
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9836866.html
Copyright © 2011-2022 走看看