viaje de Juan (POJ 1041)

tema Enlace

título Descripción

Juanito tiene un coche nuevo. Él decidió conducir por la ciudad para visitar a sus amigos. Johnny quería visitar todos sus amigos, pero no había muchos de ellos. En cada calle que tenía un amigo. Empezó a pensar cómo hacer que su viaje sea lo más corto posible. Muy pronto se dio cuenta de que la mejor manera de hacerlo era a través de los viajes cada calle de la ciudad sólo una vez. Naturalmente, él quería terminar su viaje en el mismo lugar que comenzó, en casa de sus padres.
Las calles de la ciudad de Johnny fueron nombrados por números enteros de 1 a n, n <1995. Las uniones fueron nombrados de forma independiente por números enteros de 1 a m, conecta m <= 44. No unión más de 44 calles. Todos los cruces en la ciudad tenían diferentes números. Cada calle se conecta exactamente dos uniones. No hay dos calles de la ciudad tenían el mismo número. Inmediatamente comenzó a planificar su viaje de vuelta. Si hubiera más de una ida y vuelta, él habría elegido la cual, cuando se escribe como una secuencia de números de la calle es la más pequeña lexicográfico. Pero Johnny no era capaz de encontrar incluso uno de esos de ida y vuelta.
Ayuda Johnny y escribir un programa que se encuentra el de ida y vuelta más corta deseada. Si el viaje redondo no existe el programa debe escribir un mensaje. Asumen que Johnny vidas en el cruce de la calle que termina aparece por primera vez en la entrada con el número más pequeño. Todas las calles de la ciudad son dos vías. Existe un camino de cada calle a otra calle en la ciudad. Las calles de la ciudad son muy estrechas y no hay posibilidad de dar marcha atrás al coche una vez que está en la calle

Formato de entrada

archivo de entrada consiste en varios bloques. Cada bloque describe una ciudad. Cada línea en el bloque contiene tres enteros x; y; z, donde x> 0 ey> 0 son los números de cruces que están conectados por el número de la calle z. El extremo del bloque está marcado por la línea que contiene x = y = 0. Al final del archivo de entrada hay un bloque vacío, x = y = 0.

Formato de salida

una línea de salida de cada bloque contiene la secuencia de números de la calle (los miembros individuales de la secuencia están separadas por el espacio) que describe de ida y vuelta de Johnny. Si el viaje redondo no se puede encontrar el bloque de salida correspondiente contiene el mensaje de “ida y vuelta no existe.”

Ejemplo de entrada

1 2 1
2 3 2
3 1 6
1 2 5
2 3 3
3 1 4
0 0
1 2 1
2 3 2
1 3 3
2 4 4
0 0
0 0

Ejemplo de salida

1 2 3 5 4 6
de ida y vuelta no existe.

análisis

efecto de título para cada bloque compuesto de aristas en el gráfico, determina si hay Euler requiere, si la salida mínima Euler presente lexicográfico, y de otra manera salidas "no existe ida y vuelta."
En primer lugar determina si la comunicación con y en la Fig grados si hay impar punto, si la cifra conectado y no hay un grado de singularidad punto, no hay algoritmo de búsqueda de Euler, Euler acuerdo con el pensamiento y Fleury número mínimo, de lo contrario, las cifras de Euler, la salida no existe "no existe ida y vuelta." .

algoritmo de Fleury

Fleury buscando algoritmo es un algoritmo para grafo dirigido libre de bucles Euler, la idea básica es la siguiente:
tomar cualquier vértice de la gráfica G v0, de modo que P0 = v0
acuerdo con el siguiente método asume a lo largo de Pi = v0e1v1e2 ... Eivi, llegado vértice VI, {, ..., ei e1, e2 } seleccione ei + 1 - de e (G):
. 1) y ei + 1 vi asociado
2), a menos que ningún otro lado alternativo, en caso de que no sea ei + 1 o Gi = G- {e1, e2, ..., ei} del puente
cuando ya no sea 2, los topes de algoritmo
pueden demostrar que, cuando se detiene el algoritmo, el circuito simple obtenido Pm = v0e1v1e2 ... emvm (vm = v0) de la G circuito de Euler

fuente

//#include <bits/stdc++.h>	poj不能使用万能头 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define MAXN 50
using namespace std;
struct Node{
	int v,data;
};
vector<Node> g[MAXN];
int x,y,z,start,nmax,k;
int degree[MAXN],father[MAXN],path[2005];
bool used[2005];
int cmp(Node a,Node b)
{
	return a.data<b.data;
}
int find(int x)
{
	if(x==father[x])return x;
	return father[x]=find(father[x]);
}
void Union(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x!=y)father[x]=y;
}
void euler(int u)
{
	int n=g[u].size();
	for(int i=0;i<n;i++){
		int v=g[u][i].v,num=g[u][i].data;
		if(!used[num]){
			used[num]=true;
			euler(v);
			path[++k]=num;
		}
	}
}
int main()
{
	while(scanf("%d%d",&x,&y)&&(x||y)){
		memset(used,0,sizeof(used));
		for(int i=1;i<=44;i++){
			degree[i]=0;
			father[i]=i;
			g[i].clear();
		} 
		k=0,start=min(x,y);	//边数、欧拉回路起点 
		do{		//初始化 
			scanf("%d",&z);
			g[x].push_back(Node{y,z});
			g[y].push_back(Node{x,z});
			degree[x]++;
			degree[y]++;
			Union(x,y);
		}while(scanf("%d%d",&x,&y)&&(x||y));
		int cnt=0;	//统计连通分量 
		for(int i=1;i<=44;i++)
			if(degree[i]&&i==father[i])
				cnt++;
		if(cnt>1) {
			printf("Round trip does not exist.\n");
			continue;
		}
		bool flag=false;	//标记是否存在奇度点 
		for(int i=1;i<=44;i++)
			if(degree[i]&1) flag=true;
			else sort(g[i].begin(),g[i].end(),cmp);
		if(flag) printf("Round trip does not exist.\n");
		else{
			euler(start);
			for(int i=k;i>=1;i--)
				printf("%d ",path[i]);
			printf("\n");
		}
	}
}
Se han publicado 19 artículos originales · ganado elogios 0 · Vistas 133

Supongo que te gusta

Origin blog.csdn.net/weixin_43960284/article/details/105237177
Recomendado
Clasificación