HDU 1878-欧拉回路(裸题)

欧拉回路

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


Problem Description
欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路。现给定一个图,问是否存在欧拉回路?
 

Input
测试输入包含若干测试用例。每个测试用例的第1行给出两个正整数,分别是节点数N ( 1 < N < 1000 )和边数M;随后的M行对应M条边,每行给出一对正整数,分别是该条边直接连通的两个节点的编号(节点从1到N编号)。当N为0时输入结
束。
 

Output
每个测试用例的输出占一行,若欧拉回路存在则输出1,否则输出0。
 

Sample Input
 
  
3 31 21 32 33 21 22 30
 

Sample Output
 
  
10
 

Author
ZJU
 

Source



解题思路:这题考的是一道裸的欧拉回路,那我们首先来讲讲什么是欧拉回路。

欧拉回路:就是你从一个点出发,经过所有的边一次,并且能回到起点,那么这个图就存在欧拉回路。

判定方法:
1、无向图:首先必须是个连通图,然后所有点的度数必须是偶数

2、有向图:首先还得是个连通图,然后,所有点的 入度等于出度

然后判定无向图是否为连通图我们可以dfs,或者运用并查集解决,度数的判断在输入时就可以解决

AC代码:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<map>
#include<set>
#define bug printf("*********\n");
#define mem0(a) memset(a, 0, sizeof(a));
#define mem1(a) memset(a, -1, sizeof(a));
#define in1(a) scanf("%d" ,&a);
#define in2(a, b) scanf("%d%d", &a, &b);
#define out1(a) printf("%d\n", a);
#define out2(a, b) printf("%d %d\n", a, b);
using namespace std;
typedef long long LL;
typedef pair<int, int> par;
const int mod = 1e9+7;
const int INF = 1e9+7;
const int N = 1000010;
const double pi = 3.1415926;

int n, m, head[1001], cnt, vis[1001], du[1001];

struct node
{
    int to;
    int next;
}e[1000010];

void add(int u, int v)
{
    e[cnt].to = v;
    e[cnt].next = head[u];
    head[u] = cnt ++;
}

void dfs(int k) //连通图判定(无向O(n))
{
    for(int i = head[k]; i != -1; i = e[i].next) {
        int en = e[i].to;
        if(!vis[en]) {
            vis[en] = 1;
            dfs(en);
        }
    }
}

void init()
{
    mem0(vis);
    mem1(head);
    mem0(du);
    cnt = 0;
}

int main()
{
    int x, y;
    while(~scanf("%d", &n)) {
        if(!n) break;
        in1(m);
        init();
        int flag = 0;
        for(int i = 0; i < m; i ++) {
            in2(x, y);
            du[x] ++; //度数计算
            du[y] ++;
            add(x, y);
            add(y, x); //此题为无向图
        }
        dfs(1);
        for(int i = 1; i <= n; i ++) {
            if(du[i]&1 || !vis[i]) flag = 1;
        }
        if(flag) printf("0\n");
        else printf("1\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/i_believe_cwj/article/details/80372541