P1341 Ungeordnete Buchstabenpaare (Eulersches Schaltkreisdenken)

Themenbeschreibung

Gegeben sind n verschiedene ungeordnete Buchstabenpaare (Groß-/Kleinschreibung beachten, ungeordnet bedeutet, dass die beiden Buchstaben im Buchstabenpaar vertauscht werden können). Bitte konstruieren Sie eine Zeichenfolge aus (n+1) Buchstaben, sodass jedes Buchstabenpaar in dieser Zeichenfolge vorkommt.

Eingabeformat

Die erste Zeile gibt eine positive ganze Zahl n ein.

Die zweite bis (n+1) Zeile enthält zwei Buchstaben in jeder Zeile, was darauf hinweist, dass die beiden Buchstaben benachbart sein müssen.

Ausgabeformat

Geben Sie eine Zeichenfolge aus, die die Anforderungen erfüllt.

Wenn es keine Zeichenfolge gibt, die die Anforderung erfüllt, geben Sie sie aus  No Solution.

Wenn mehrere Schemata vorhanden sind, geben Sie bitte das Schema mit der kleinsten lexikografischen Reihenfolge aus (d. h. der ASCII-Code, der die vorhergehenden Buchstaben erfüllt, ist so klein wie möglich).

Eingabe- und Ausgabebeispiele

Geben Sie zum Kopieren #1 ein

4
Die
tZ
Xt
Axt

Ausgabe Nr. 1 Kopie

XaZtX
 

Wissenspunkte:

Ein Pfad in einem Graphen G heißt Euler-Pfad, wenn er jede Kante genau einmal enthält.

Wenn ein Kreis ein Euler-Pfad ist, wird er Euler-Kreis genannt.

Der einfache Punkt ist: Von einem Punkt aus werden alle Seiten einmal durchlaufen.

Probleme lösen:

1. Verwenden Sie die Optimierung der Union-Suche, um zu bestimmen, ob es sich um eine Euler-Schaltung handelt. Dies ist nur ein verbundener Block. Ein Bild sagt mehr als tausend Worte:

 2. Für ungerichtete Graphen. Wenn alle Punkte im Diagramm gerade Punkte sind, liegt ein Euler-Kreis vor, und jeder Punkt ist in Ordnung. Wenn es nur zwei ungerade Punkte gibt, liegt eine Euler-Straße vor, bei der ein singulärer Punkt der Startpunkt und der andere der Endpunkt ist.

 Code:

Beachten Sie auch hier, dass es sich um dfs handelt. Beginnen Sie also mit n-- und nicht mit 0

#include<bits/stdc++.h>
using namespace std;
int n,f[10005], b[1005][1005], flag, d[10005];
char ans[10005], s[5];
int find(int x) { // 并查集
	if (x != f[x]) f[x] = find(f[x]);
	return f[x];
}
void dfs(int x) {
	for (int i = 64; i <= 125; i++) {
		if (b[x][i]) {
			b[x][i] = b[i][x] = 0;
			dfs(i);
		}
	}
	ans[n--] = x; //到底 在退回
}
int main() {
	ios::sync_with_stdio(0);
	cin >> n;
	for (int i = 64; i <= 125; i++) f[i] = i;
	for (int i = 1; i <= n; i++) {
		cin >> s;
		b[s[0]][s[1]] = 1;
		b[s[1]][s[0]] = 1;
		d[s[0]]++; // 处在入读in
		d[s[1]]++;
		int fx = find(s[0]), fy = find(s[1]);
		f[fx] = fy;//合并
	}

	int cnt = 0;
	for (int i = 64; i <= 125; i++) {
		if (f[i] == i && d[i])cnt++;
	}
	if (cnt != 1)cout << "No Solution" << endl;//判断是否为欧拉
	else {
		cnt = 0;
		flag = 0;
		for (int i = 64; i <= 125; i++) {
			if (d[i] % 2 == 1) {
				cnt++;
				if (flag == 0) flag = i; // 入度要为奇数是为0 或者为2
			}
		}

		if (cnt && cnt != 2) { 
			cout << "No Solution" << endl;
			return 0;
		}

		if (flag == 0) {
			for (int i = 64; i <= 125; i++) {
				if (d[i]) {
					flag = i;
					break; //最小的开始搜
				}
			}
		}
		dfs(flag);
		printf("%s", ans);
	}
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/zhi6fui/article/details/129651583
Recomendado
Clasificación