ACM: SGU 101 Domino- 欧拉回路-并查集

sgu 101 - Domino

Time Limit:250MS     Memory Limit:4096KB     64bit IO Format:%I64d & %I64u

Description

Dominoes – game played with small, rectangular blocks of wood or other material, each identified by a number of dots, or pips, on its face. The blocks usually are called bones, dominoes, or pieces and sometimes men, stones, or even cards.
The face of each piece is divided, by a line or ridge, into two squares, each of which is marked as would be a pair of dice...

The principle in nearly all modern dominoes games is to match one end of a piece to another that is identically or reciprocally numbered.

ENCYCLOPÆDIA BRITANNICA

Given a set of domino pieces where each side is marked with two digits from 0 to 6. Your task is to arrange pieces in a line such way, that they touch through equal marked sides. It is possible to rotate pieces changing left and right side.

Input

The first line of the input contains a single integer N (1 ≤ N ≤ 100) representing the total number of pieces in the domino set. The following N lines describe pieces. Each piece is represented on a separate line in a form of two digits from 0 to 6 separated by a space.

Output

Write “No solution” if it is impossible to arrange them described way. If it is possible, write any of way. Pieces must be written in left-to-right order. Every of N lines must contains number of current domino piece and sign “+” or “-“ (first means that you not rotate that piece, and second if you rotate it).

Sample Input

5
1 2
2 4
2 4
6 4
2 1

Sample Output

2 -
5 +
1 +
3 +
4 -

//这个题目做了我一个晚上,有点头晕,还是要让自己保持冷静啊。。。

//多米诺骨牌有两个面,每个面有一个数字,相同的数字只能推倒相同数字面的骨牌,骨牌可以转向,给出的数字是严格的正面反面,问是否能推到所有的骨牌。

//如果可以输出骨牌的顺序和是否需要反转骨牌。如果不可以全部推倒,输出"No solution"

//AC代码:


#include"algorithm"
#include"iostream"
#include"cstring"
#include"cstdlib"
#include"string"
#include"cstdio"
#include"vector"
#include"cmath"
#include"queue"
using namespace std;
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(x))
#define MX 401

bool vis[MX];
int Head[MX],cnt;
int indegree[MX],p[MX],siz,bin;
int fid[7];

struct Edge {
	int v,nxt;
	int flag;
} E[MX];

int find(int x) {
	return fid[x]==x?x:(fid[x]=find(fid[x]));
}

void union_root(int st,int ed) {
	int rt1=find(st);
	int rt2=find(ed);
	if(rt1!=rt2)fid[rt2]=rt1;
}

void edge_init() {
	cnt=0;
	siz=0;
	memset(p,0);
	memset(E,0);
	memset(vis,0);
	memset(Head,-1);
	memset(indegree,0);
	for(int i=0; i<=6; i++) {
		fid[i]=i;
	}
}

void edge_add(int st,int ed,int flag) {
	E[cnt].v=ed;
	E[cnt].flag=flag;
	E[cnt].nxt=Head[st];
	Head[st]=cnt++;
}

bool check() {
	bin=-1;
	int tot=0;
	for(int i=0; i<=6; i++) {
		if(vis[i]) {
			if(bin==-1)bin=i;
			if(indegree[i]%2) {
				tot++;
				if(tot>2)return 0;//判断奇数有多少个,超过两个奇数就判断不是
				bin=i;
			}
		}
	}
	for(int i=0; i<=6; i++) {
		if(bin!=-1)if(indegree[i]&&find(i)!=find(bin))return 0;  //如果不是联通块就判断不是
	}
	if(bin==-1)return 0;
	if(tot==1)return 0;	//如果奇数只有一个判断不是
	else return 1;
}

void Fleury(int u,int e) {
	for(int i=Head[u]; ~i; i=E[i].nxt) {
		int v=E[i].v;
		if(vis[i|1])continue;
		vis[i|1]=1;
		Fleury(v,E[i].flag);
	}
	if(e)p[siz++]=e;	//标记是哪一条边。
}

int main() {
	int m,st,ed;
	while(~scanf("%d",&m)) {
		edge_init();
		for(int i=1; i<=m; i++) {
			scanf("%d%d",&st,&ed);
			vis[st]=vis[ed]=1;
			edge_add(st,ed,i);		//正向
			edge_add(ed,st,-i);		//记录多米诺骨牌是否需要转向  反向
			indegree[st]++;
			indegree[ed]++;
			union_root(st,ed);		//合成联通块
		}
		bool flag=check();
		if(!flag)puts("No solution");
		else {
			memset(vis,0);	//再次清空标记数组
			Fleury(bin,0);
			for(int i=siz-1; i>=0; i--) {
				printf("%d %c\n",p[i]>0?p[i]:-p[i],p[i]>0?‘+‘:‘-‘);
			}
		}
	}
	return 0;
}

  

时间: 2024-12-27 13:31:25

ACM: SGU 101 Domino- 欧拉回路-并查集的相关文章

ACM: FZU 2112 Tickets - 欧拉回路 - 并查集

FZU 2112 Tickets Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Practice Description You have won a collection of tickets on luxury cruisers. Each ticket can be used only once, but can be used in either direction between

SGU 101. Domino 欧拉回路

无向图欧拉回路 欧拉通路 #include <cstdio> #include <cstring> using namespace std; struct edge { int v, next, b, id; }e[210]; int vis[210]; int first[10], cnt; int ans[210], len; int f[10]; int find(int x) { if(x != f[x]) return f[x] = find(f[x]); return

[ACM] POJ 3295 Ubiquitous Religions (并查集)

Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23093   Accepted: 11379 Description There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in findi

[ACM] POJ 1611 The Suspects (并查集,输出第i个人所在集合的总人数)

The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 21586   Accepted: 10456 Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. T

HDU1116(欧拉回路+并查集)

先用并查集来判断图是否连通,然后再根据欧拉回路的出度和入度的性质来判断是否为欧拉回路. 关键是建边,我们可以把字符串看成是一条边,首字母为出发点,尾字母为目的点,建边. #include <stdio.h> #include <string.h> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <math.

poj 2513 欧拉回路+并查集判断是否联通+Trie树

http://poj.org/problem?id=2513 最初看到 第一感觉---map  一看250000的数据量 果断放弃 然后记得以前看过,trie代替map,尤其当数据量特别大的时候 学到了: 1.Trie代替map的思想,可以在单词结尾的tree[i][tk]  这个i作为字符串对应的int值 ,当然这个int值也可以用于建立并查集 2.接上,通过并查集判断,所有的点在同一个集合图就是联通的,否则不联通,注意tree[i][tk]>0 表示是单词结尾, x=Find(x);//这句

HDU 1116 || POJ 1386 || ZOJ 2016 Play on Words (欧拉回路+并查集)

题目链接 题意 : 有很多门,每个门上有很多磁盘,每个盘上一个单词,必须重新排列磁盘使得每个单词的第一个字母与前一个单词的最后一个字母相同.给你一组单词问能不能排成上述形式. 思路 :把每个单词看成有首字母指向尾字母的有向边,每个字母看成一个点,题中要求等效于判断图中是否存在一条路径经过每一条一次且仅一次,就是有向欧拉通路.统计个顶点的出入度,如果每个点的出入度都相同,那就是欧拉回路,如果有两个奇数度,那就是欧拉通路,除此之外,都不能满足要求.还有别忘了判断是否连通,此时用到并查集,图中所有的边

UVA - 10129 Play on Words(欧拉回路+并查集)

2.解题思路:本题利用欧拉回路存在条件解决.可以将所有的单词看做边,26个字母看做端点,那么本题其实就是问是否存在一条路径,可以到达所有出现过的字符端点.由于本题还要求了两个单词拼在一起的条件是前一个单词的右端点和本单词的左端点一样.所以这是一个有向图.根据结论:有向图的底图(忽略边的方向后的图)必须连通:有向图中最多只能有两个端点的入度不等于出度,且必须是其中一点的入度比出度小1,另一点的入度比出度大1.因此先判断端点是否都连通,再判断每个端点的度数是否满足结论即可. 那么,如何判断连通性呢?

nyist 42 一笔画 (欧拉回路 + 并查集)

nyoj42 分析: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径. 若该路径是一个圈,则称为欧拉(Euler)回路. 具有欧拉回路的图称为欧拉图(简称E图).具有欧拉路径但不具有欧拉回路的图称为半欧拉图. 先说一下欧拉路径.欧拉回路的充要条件: 1.无向连通图G是欧拉图,当且仅当G不含奇数度结点(G的所有结点度数为偶数): 2.无向连通图G含有欧拉通路,当且仅当G有零个或两个奇数度的结点: 3.有向连通图D是欧拉图,当且仅当该图为连通图且D中每个结点的入度=出度