zoukankan      html  css  js  c++  java
  • 欧拉回路基础 HDU1878 欧拉回路||并差集

    欧拉回路

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 10544    Accepted Submission(s): 3845


    Problem Description
    欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
     
    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
    束。
     
    Output
    每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
     
    Sample Input
    3 3 1 2 1 3 2 3 3 2 1 2 2 3 0
     
    Sample Output
    1 0
     
    Author
    ZJU
     
    Source
     
    Recommend
    We have carefully selected several similar problems for you:  1877 1881 1863 1875 1864
     
     
     
     
     
     
    附:
     
    ps赤裸裸的欧拉回路,下面两个没有注视是我写的,没有注视,可以作为模板,带有注视的是网上的,便于理解
     
     
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=1005;
    int map[maxn][maxn];
    bool vis[maxn];
    int indegree[maxn],father[maxn];
    int n,m;
    void init(){
         for(int i=1;i<=n;i++)
            father[i]=i;
    }
    int find(int u){
       if(father[u]!=u)
        father[u]=find(father[u]);
       return father[u];
    }
    void Union(int x,int y){
        int t1=find(x);
        int t2=find(y);
        if(t1!=t2)
        father[t1]=t2;
    }
    int main(){
    
       while(scanf("%d",&n)&&n){
    init();
           memset(map,0,sizeof(map));
           memset(indegree,0,sizeof(indegree));
           memset(vis,false,sizeof(vis));
           scanf("%d",&m);
           for(int i=1;i<=m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            map[u][v]=map[v][u]=1;
            Union(u,v);
            indegree[u]++;
            indegree[v]++;
           }
           bool flag=false;
          int sum=0;
          for(int i=1;i<=n;i++){
                if(father[i]==i){
                    sum++;
                }
            if(indegree[i]%2==1){
                flag=true;
                break;
            }
          }
    
          if(flag==true||sum!=1)
            printf("0
    ");
          else
            printf("1
    ");
    
       }
       return 0;
    }
     
        感谢大神
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int maxn=1005;
    int map[maxn][maxn];
    bool vis[maxn];
    int indegree[maxn];
    int n,m;
    void dfs(int u){
      vis[u]=true;
      for(int i=1;i<=n;i++)
        if(!vis[i]&&map[u][i])
        dfs(i);
        return ;
    }
    int main(){
        while(scanf("%d",&n)&&n){
                scanf("%d",&m);
            memset(map,0,sizeof(map));
            memset(vis,false,sizeof(vis));
            memset(indegree,0,sizeof(indegree));
            for(int i=0;i<m;i++){
                int u,v;
                scanf("%d%d",&u,&v);
                indegree[u]++;
                indegree[v]++;
                map[u][v]=map[v][u]=1;
            }
    
            dfs(1);
            int i;
            for( i=1;i<=n;i++){
                if(!vis[i]||indegree[i]%2==1)
                    break;
            }
            if(i>n)
                printf("1
    ");
            else
                printf("0
    ");
        }
        return 0;
    }
    //本题主要考察欧拉回路的两个充要条件:1.联通图 2.顶点度数都为偶数 (两个条件缺一不可)
    
    #include<stdio.h>
    #include<string.h>
    
    int graph[1000][1000]; //采用邻接矩阵存储图
    int visit[1000]; //在遍历时标记该点是否被访问过
    int degree[1000]; //存储节点的度
    
    void DFS(int v, int n) { //深度优先遍历,递归
        visit[v] = 1;
        for(int i=1; i<=n; i++)
            if(graph[v][i]  && visit[i]==0)
                DFS(i,n);
    }
    
    int main() {
        //freopen("in.txt","r",stdin);
        int n, m;
        while(scanf("%d %d",&n,&m)!=EOF && n) {
            memset(graph,0,sizeof(graph)); //清零
            memset(visit,0,sizeof(visit));
            memset(degree,0,sizeof(degree));
            int a, b, i;
            int flag = 1; //标记是否存在欧拉回路
            for(i=0; i<m; i++) {
                scanf("%d %d",&a,&b);
                graph[a][b] = graph[b][a] = 1; //"1"表示两点属于邻接关系
                degree[a]++; degree[b]++;
            }
            DFS(1,n);
            for(i=1; i<=n; i++) {
                if(visit[i] == 0) {
                    flag = 0; //若有点未曾被访问,即一次深度遍历有未访问的点,则不存在欧拉回路
                    break;
                }
                if(degree[i] % 2 != 0) {
                    flag = 0; //若有点的度不是偶数,则不存在欧拉回路
                    break;
                }
            }
            if(flag)
                printf("1
    ");
            else
                printf("0
    ");
        }
    
        return 0;
    }
  • 相关阅读:
    golang 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
    BITOP operation destkey key [key ...]
    Viscosity for Mac使用创建您的第一个连接的方法
    ubuntu18没有网络连接Network
    go1.14下Go mod使用实践
    Unity 光照系统
    Unity 单例模式
    Unity 回调函数(Callback)
    Unity 基于OnGUI显示实时FPS
    Unity OnGUI 的可视化编辑
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4713711.html
Copyright © 2011-2022 走看看