Camino más largo (mapa de competencia + mapa de Hamilton + lista para encontrar el camino)

Inserte la descripción de la imagen aquíInserte la descripción de la imagen aquíInserte la descripción de la imagen aquí
El significado de la pregunta: Dado un gráfico dirigido, la condición de restricción de este gráfico dirigido es que solo puede haber un borde dirigido entre dos puntos. Comience desde cualquier punto y cada punto solo puede ir una vez. Pregunte al más largo ¿Cuál es el ruta, la respuesta no es única, solo genera una;
si analiza cuidadosamente el significado de esta pregunta, puede saber que si se elimina la dirección del gráfico dirigido, entonces el gráfico no dirigido es un gráfico completamente no dirigido. Si ya conociste una imagen de la competencia, entonces debes saber que esta es una imagen de la competencia, y yo simplemente lo sé. Baidu echó un vistazo a lo que es la imagen de la competencia:
Inserte la descripción de la imagen aquí
entonces la imagen de la competencia tiene una característica: Inserte la descripción de la imagen aquí
entonces sabes que es un gráfico de Hamilton: Sí Comience desde un punto y pase por todos los puntos, y el punto solo pasa una vez.
Entonces sé que la longitud de la ruta más larga es v-1, v es el número de vértices, luego los vértices pasados ​​deben ser todos vértices, y debe haber una ruta;
así que creo que la lista utilizada para resolver el problema es muy inteligente para mantener;
La siguiente es la explicación de la solución:
Inserte la descripción de la imagen aquí
De acuerdo con el significado de la solución, puedo entender esto:
Inserte la descripción de la imagen aquí
un punto adyacente, el nodo predecesor debe apuntar a este punto, y este punto debe apuntar al nodo sucesor;
entonces la respuesta se puede obtener directamente ejecutando la lista una vez;
Debo decir que es realmente inteligente mantener con la lista;
Código de CA:

#include<bits/stdc++.h>
using namespace std;
int Map[510][510];
list<int> List;
int main(){
    
    
	int T;
	scanf("%d",&T);
	while(T--){
    
    
		int v;
		scanf("%d",&v);
		for(int i=1;i<=v;i++){
    
    //初始化图 
			  for(int j=1;j<=v;j++){
    
    
			  	scanf("%d",&Map[i][j]);
			  }
		}
		List.push_back(1);//从1号节点出发 
		for(int i=2;i<=v;i++){
    
    
			   int out=0,in=0;
			   for(list<int>::iterator it=List.begin();it!=List.end();it++){
    
    
			   	  if(Map[i][*it])out++;//i点 指向链表里面的个数 
			   	  else in++;//链表里面的指向i点的个数 
			   }
			   //cout<<in<<""<<out<<endl;
			   if(out==List.size())List.push_front(i);//如果i点指向List中的所有点 
			   else if(in==List.size())List.push_back(i);//如果i点被List中的所有点指向 
			   else{
    
    
			   	list<int>::iterator it=List.begin(),next;
			   	   for(;;it++){
    
    
					    next=it;next++;
					      if(next==List.end())break;
					      if(Map[*it][i]&&Map[i][*next]){
    
    
					      	 break; 
						  }
					  }
			   	   List.insert(next,i);//加入两个点之间,如果没有那么就加在最后面
			   }
		}
		for(list<int>::iterator it=List.begin();it!=List.end();it++){
    
    
			printf("%d ",*it);
		}
		puts("");
		List.clear();
	}
	return 0;
} 

Supongo que te gusta

Origin blog.csdn.net/qq_44555205/article/details/104555076
Recomendado
Clasificación