您的位置:首页 > 其它

UVa 10596 - Morning Walk

2015-10-09 20:26 302 查看
題目:Kamal早上散步,發現有很多條路,問能否每條路走一次回到原點。

分析:圖論,歐拉迴路,并查集。判斷是否存在歐拉迴路。

歐拉迴路存在條件:1.有邊的點度數為偶數,2.右邊的點構成的圖聯通。

說明:╮(╯▽╰)╭。

#include <cstdlib>
#include <cstring>
#include <cstdio>

#define NODE_SIZE 202
#define EDGE_SIZE 10001

int degree[NODE_SIZE];

typedef struct _edge
{
	int point1;
	int point2;
}edge;
edge E[EDGE_SIZE];

//union_set
int sets[NODE_SIZE];
int rank[NODE_SIZE];

void set_inital(int a, int b)
{
	for (int i = a; i <= b; ++ i) {
		rank[i] = 0;
		sets[i] = i;
	}
}

int set_find(int a)
{
	if (a != sets[a])
		sets[a] = set_find(sets[a]);
	return sets[a];
}

void set_union(int a, int b)
{
	if (rank[a] < rank[b])
		sets[a] = b;
	else {
		if (rank[a] == rank[b])
			rank[a] ++;
		sets[b] = a;
	}
}
//end_union_set

int euler(int n, int m)
{
	memset(degree, 0, sizeof(degree));
	set_inital(0, n);
	for (int i = 0; i < m; ++ i) {
		int A = set_find(E[i].point1);
		int B = set_find(E[i].point2);
		if (A != B) set_union(A, B);
		degree[E[i].point1] ++;
		degree[E[i].point2] ++;
	}
	int ans = 0, flag = 0;
	for (int i = 0; i < n; ++ i) {
		if (degree[i]) ans += (sets[i]==i);
		if (degree[i]%2) flag = 1;
	}
	
	return (ans == 1 && !flag);
}

int main()
{
	int n, m;
	while (~scanf("%d%d",&n,&m)) {
		for (int i = 0; i < m; ++ i)
			scanf("%d%d",&E[i].point1,&E[i].point2);
		
		if (euler(n, m))
			printf("Possible\n");
		else printf("Not Possible\n");
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: