• 九度oj题目1027:欧拉回路


    题目1027:欧拉回路

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:2844

    解决:1432

    题目描述:
        欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
    输入:
        测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
    输出:
        每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
    样例输入:
    3 3
    1 2
    1 3
    2 3
    3 2
    1 2
    2 3
    0
    样例输出:
    1
    0
    来源:
    2008年浙江大学计算机及软件工程研究生机试真题

    注意:代码中的i要从1开始,要与题目匹配!!

    欧拉回路定义:

    若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径。若该路径是一个圈(首尾相连),则称为欧拉(Euler)回路。

    判断是否存在欧拉回路的准则:

    有向图:图连通,所有的顶点出度=入度。

    无向图:图连通,所有顶点都是偶数度。

    程序实现一般是如下过程:

    1.利用并查集判断图是否连通,即判断p[i] < 0的个数,如果大于1,说明不连通。

    2.根据出度入度个数,判断是否满足要求。

    3.利用dfs输出路径。

    学习代码:

      1 /***************************************************
      2 
      3 题目描述:
      4         欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
      5 
      6 输入:
      7         测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结束。
      8 
      9 输出:
     10         每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
     11 
     12 样例输入:
     13 
     14     3 3
     15     1 2
     16     1 3
     17     2 3
     18     3 2
     19     1 2
     20     2 3
     21     0
     22 
     23 样例输出:
     24 
     25     1
     26     0
     27 
     28 
     29 **************************************************/
     30 #include <cstdio>
     31 #include <cstring>
     32 
     33 using namespace std;
     34 
     35 const int N = 1000 + 10;
     36 
     37 int n, m;
     38 int g[N][N];
     39 int degree[N];
     40 int p[N];
     41 
     42 int union_find(int x);
     43 void disjoint_union(int a, int b);
     44 bool check();
     45 
     46 int main()
     47 {
     48     #ifndef ONLINE_JUDGE
     49         freopen("e:\uva_in.txt", "r", stdin);
     50     #endif // ONLINE_JUDGE
     51 
     52     while (scanf("%d", &n) == 1)
     53     {
     54         if (n == 0)
     55             break;
     56 
     57         scanf("%d", &m);
     58         memset(degree, 0, sizeof(degree));
     59         memset(p, -1, sizeof(p));
     60 
     61         for (int i = 0; i < m; i++) {
     62             int a, b;
     63             scanf("%d%d", &a, &b);
     64             degree[a]++;
     65             degree[b]++;
     66             disjoint_union(a, b);
     67         }
     68 
     69         if (check())
     70             printf("1
    ");
     71         else
     72             printf("0
    ");
     73     }
     74     return 0;
     75 }
     76 
     77 int union_find(int x)
     78 {
     79     if (p[x] < 0)
     80         return x;
     81 
     82     return p[x] = union_find(p[x]);
     83 }
     84 
     85 void disjoint_union(int a, int b)
     86 {
     87     int pa = union_find(a);
     88     int pb = union_find(b);
     89 
     90     if (pa == pb)
     91         return;
     92 
     93     if (pa < pb)
     94         p[pb] = pa;
     95     else
     96         p[pa] = pb;
     97 }
     98 
     99 bool check()
    100 {
    101     int cnt = 0;
    102     for (int i = 1; i <= n; i++) {
    103         cnt += (p[i] < 0);
    104         if (degree[i] & 1)
    105             return false;
    106     }
    107 
    108     if (cnt != 1)
    109         return false;
    110 
    111     return true;
    112 }

    自己的代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <string>
     4 #include <queue>
     5 #include <vector>
     6 #include <stack>
     7 #include <iostream>
     8 using namespace std;
     9 int fa[1005],degree[1005];
    10 int findfa(int a){
    11     if(fa[a]!=a){
    12         fa[a]=findfa(fa[a]);
    13     }
    14     return fa[a];
    15 }
    16 int main(){
    17     //freopen("D:\INPUT.txt","r",stdin);
    18     int n,m;
    19     while(scanf("%d",&n)!=EOF){
    20         if(!n){
    21             break;
    22         }
    23         memset(degree,0,sizeof(degree));
    24         scanf("%d",&m);
    25         int i;
    26         for(i=0;i<=n;i++){
    27             fa[i]=i;
    28         }
    29         int u,v;
    30         for(i=0;i<m;i++){
    31             scanf("%d %d",&u,&v);
    32             degree[u]++;
    33             degree[v]++;
    34             int fu=findfa(u);
    35             int fv=findfa(v);
    36             if(fu>fv){
    37                 fa[fv]=fu;
    38             }
    39             else{
    40                 fa[fu]=fv;
    41             }
    42         }
    43         int num=0;
    44         for(i=1;i<=n;i++){
    45             if(fa[i]==i){
    46                 num++;
    47             }
    48         }
    49         if(num!=1){//整体不联通,整个图不止一个集合.好好体会!!
    50             cout<<0<<endl;
    51             continue;
    52         }
    53         int odd=0;
    54         for(i=1;i<=n;i++){
    55             if(degree[i]%2){
    56                 odd++;
    57             }
    58         }
    59         if(odd){//不是所有点的度数均为偶数
    60             cout<<0<<endl;
    61             continue;
    62         }
    63         //全图联通并且所有点的度数均为偶数
    64         cout<<1<<endl;
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    springboot新手脱坑之无法下载依赖包
    07_mybatis延迟加载
    05_mybatis动态sql
    04_Mybatis输入出映射
    C#-----类FileStream的使用
    JavaWeb-----JSP详解
    JavaWeb-----ServletConfig对象和servletContext对象
    JavaWeb-----实现第一个Servlet程序
    JavaScript--浅谈!=、!==、==和===的区别
    EasyUI学习-----表格DataGrid格式化formatter用法
  • 原文地址:https://www.cnblogs.com/Deribs4/p/4648347.html
Copyright © 2020-2023  润新知