PAT (Advanced Level) 1126. Eulerian Path (25)

1126. Eulerian Path (25)

时间限制
300 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

In graph theory, an Eulerian path is a path in a graph which visits every edge exactly once. Similarly, an Eulerian circuit is an Eulerian path which starts and ends on the same vertex. They were first discussed by Leonhard Euler while solving the famous Seven Bridges of Konigsberg problem in 1736. It has been proven that connected graphs with all vertices of even degree have an Eulerian circuit, and such graphs are called Eulerian. If there are exactly two vertices of odd degree, all Eulerian paths start at one of them and end at the other. A graph that has an Eulerian path but not an Eulerian circuit is called semi-Eulerian. (Cited from https://en.wikipedia.org/wiki/Eulerian_path)

Given an undirected graph, you are supposed to tell if it is Eulerian, semi-Eulerian, or non-Eulerian.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 2 numbers N (<= 500), and M, which are the total number of vertices, and the number of edges, respectively. Then M lines follow, each describes an edge by giving the two ends of the edge (the vertices are numbered from 1 to N).

Output Specification:

For each test case, first print in a line the degrees of the vertices in ascending order of their indices. Then in the next line print your conclusion about the graph -- either "Eulerian", "Semi-Eulerian", or "Non-Eulerian". Note that all the numbers in the first line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

Sample Input 1:
7 12
5 7
1 2
1 3
2 3
2 4
3 4
5 2
7 6
6 3
4 5
6 4
5 6
Sample Output 1:
2 4 4 4 4 4 2
Eulerian
Sample Input 2:
6 10
1 2
1 3
2 3
2 4
3 4
5 2
6 3
4 5
6 4
5 6
Sample Output 2:
2 4 4 4 3 3
Semi-Eulerian
Sample Input 3:
5 8
1 2
2 5
5 4
4 1
1 3
3 2
3 4
5 3
Sample Output 3:

3 3 4 3 3
Non-Eulerian
刚看到这道题,我的内心是崩溃的~因为首先,我连题目标题的第一个单词我都不懂。。。后来云里雾里的读完题目觉得这道题应该是图吧~然后就没有然后了。。。。
后来我百度了一下, Eulerian这个单词的意思,原来是一位著名的数学家欧拉的名字~~

考完的大佬有的说这道题其实不懂欧拉环路,欧拉路径,半欧拉环路,都可以做的出来,因为是一道英语阅读理解的题目~

好吧。。。我不得不说,在下委实不敢苟同。。。不懂欧拉环路的前提下,我再去看了一边题目,发现还是很晕。。。

于是,我百度了一下,简单来说,欧拉环路就是图中的每个点的度(有向图分出度入度,无向就不分啦~这道题很幸运的是无向滴

~)都是偶数,半欧拉就是所有的点里面,有且只有两个点的度是奇数~剩下的非欧拉的情况就是度为奇数的点个数为1或者大于2

于是我很沾沾自喜的写好了代码,但是AC不了,有一个测试点过不去,,,后来再去看一位大神的博客,发现他提到了要注意图是

不是联通的~~~

所以,综上,这道题的思路就是先判断图联通否?联通的话,再去看每个点的度奇偶性啦~

遍历图当然用DFS~~

#include<cstdio>
#include<cstring>

using namespace std;

const int maxn = 510;

int G[maxn][maxn], weight[maxn];
int n, m;
bool vis[maxn] = { false };

void dfs(int index) {
	for (int i = 1; i <= n; i++) {
		if (vis[i] == false && G[index][i] != 0) {
			vis[i] = true;
			dfs(i);
		}
	}
}

int main() {

	memset(weight, 0, sizeof(weight));

	scanf("%d %d", &n, &m);

	int a, b;
	for (int i = 0; i < m; i++) {
		scanf("%d %d", &a, &b);
		weight[a]++;
		weight[b]++;
		G[a][b] = 1;
		G[b][a] = 1;
	}

	int ss = 0;
	for (int i = 1; i <= n; i++) {
		printf("%d", weight[i]);
		if (weight[i] % 2 != 0) {           //如果为奇数,记录这样的点的个数
			ss++;
		}
		if (i < n) {
			printf(" ");
		}
		else {
			printf("\n");
		}
	}

	int f = 0;
	for (int t = 1; t <= n; t++) {
		if (!vis[t])
		{
			vis[t] = true;
			dfs(t);
		}
		else {
			continue;
		}
		if (f == 1) {
			printf("Non-Eulerian\n");
			return 0;
		}
		f++;                //如果是第一次dfs全部遍历一遍图的话,那就一直continue,不会再判断;不然还会降落到判断的哦
	}

	if (ss == 0) {
		printf("Eulerian\n");
	}
	else if (ss == 2) {
		printf("Semi-Eulerian\n");
	}
	else {
		printf("Non-Eulerian\n");
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值