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

    题目描述:

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

    一共两个子任务:

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

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

    输入格式:

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

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

    接下来 mmm 行中,第 iii 行两个整数 vi,uiv_i, u_ivi,ui,表示第 iii 条边(从 111 开始编号)。保证 1≤vi,ui≤n1 leq v_i, u_i leq n1vi,uin。

    1. 如果 t=1t = 1t=1 则表示 viv_ivi 到 uiu_iui 有一条无向边。

    2. 如果 t=2t = 2t=2 则表示 viv_ivi 到 uiu_iui 有一条有向边。

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

    输出格式:

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

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

    1. 如果 t=1t = 1t=1,输出 mmm 个整数 p1,p2,…,pmp_1, p_2, dots, p_mp1,p2,,pm。令 e=∣pi∣e = lvert p_i verte=pi∣,那么 eee 表示经过的第 iii 条边的编号。如果 pip_ipi 为正数表示从 vev_eve 走到 ueu_eue,否则表示从 ueu_eue 走到 vev_eve

    2. 如果 t=2t = 2t=2,输出 mmm 个整数 p1,p2,…,pmp_1, p_2, dots, p_mp1,p2,,pm。其中 pip_ipi 表示经过的第 iii 条边的编号。

    根据题目名称我们得知这道题是一道判断欧拉回路的板子题,那么怎么判欧拉回路?

    如果这个图是无向图,那么对于每个点,它的度都要是偶数。然后路径就是在这个图上随便找一个点开始,随便跑,只要不重复就行。

    如果这个图是有向图,那么对于每个店,它的入度和出度要一样。然后从图上一个有出边的点遍历。

    就是要注意无向图时,如果a->b这条边跑过了,那么b->a这条边也要标记,而且存边时也要注意细节。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define in(a) a=read()
    #define REP(i,k,n) for(int i=k;i<=n;i++)
    #define MAXN 2000010
    using namespace std;
    inline int read(){
        int x=0,t=1,c;
        while(!isdigit(c=getchar())) if(c=='-') t=-1;
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        return x*t;
    }
    int t,n,m;
    int total=0,head[MAXN],to[MAXN<<1],nxt[MAXN<<1];
    int ans[MAXN<<1],ind,vis[MAXN<<1];
    int In[MAXN],out[MAXN],du[MAXN];
    inline void adl(int a,int b){
        total++;
        to[total]=b;
        nxt[total]=head[a];
        head[a]=total;
        return ;
    }
    inline void dfs(int u){
        for(int &e=head[u];e;e=nxt[e])
            if(!vis[e]){
                int k=e;
                vis[e]=1;
                if(t==1){//标记细节
                    if(e%2)  vis[e+1]=1;
                    else  vis[e-1]=1;
                }
                dfs(to[e]);
                ans[++ind]=k;
            }
        return ;
    }
    int main(){
        in(t),in(n),in(m);
        int a,b;
        if(t==1){
            REP(i,1,m)
                in(a),in(b),du[a]++,du[b]++,adl(a,b),adl(b,a);
            REP(i,1,n)
                if(du[i]%2){
                    cout<<"NO"<<endl;
                    return 0;
                }
        }
        if(t==2){
            REP(i,1,m)
                in(a),in(b),In[b]++,out[a]++,adl(a,b);
            REP(i,1,n)
                if(In[i]!=out[i]){
                    cout<<"NO"<<endl;
                    return 0;
                }
        }
        REP(i,1,n)
            if(head[i]){
                dfs(i);
                break;
            }
        if(ind!=m){
               cout<<"NO";
               return 0;
        }
        cout<<"YES"<<endl;
        if(t==2){
            REP(i,0,ind-1)
                printf("%d ",ans[ind-i]);
            return 0;
        }
        REP(i,0,ind-1){
             if(ans[ind-i]%2)  printf("%d ",(ans[ind-i]+1)/2);//输出细节
             else  printf("%d ",ans[ind-i]/(-2));
         }
        return 0;
    }
  • 相关阅读:
    Java入门——day42
    第六周进度报告
    Java入门——day41
    Java入门——day40
    Java入门——day39
    Java入门——day38
    Java入门——day37
    Java入门——day36
    Java入门——day35
    第五周进度报告
  • 原文地址:https://www.cnblogs.com/jason2003/p/9754629.html
Copyright © 2011-2022 走看看