Longest Path (competition map + Hamilton map + list to find the path)

Insert picture description hereInsert picture description hereInsert picture description here
The meaning of the question: Given a directed graph, the restriction condition of this directed graph is that there can only be one directed edge between any two points. Start from any point and each point can only go once. Ask the longest What is the path, the answer is not unique, just output one;
if you carefully analyze the meaning of this question, you can know that if the direction of the directed graph is removed, then the undirected graph is a completely undirected graph. If you have met a competition picture before, then you must know that this is a competition picture, and I just know it. Baidu took a look at what the competition picture is:
Insert picture description here
then the competition picture has one characteristic: Insert picture description here
so you know that it is a Hamilton chart: Yes Start from one point and pass through all points, and the point only passes once.
So I know that the longest path length is v-1, v is the number of vertices, then the vertices passed must be all vertices, and there must be a path;
so I think the list used to solve the problem is very clever to maintain ;
The following is the explanation of the solution:
Insert picture description here
According to the meaning of the solution, I can understand this:
Insert picture description here
an adjacent point, the predecessor node must point to this point, and this point must point to the successor node;
so the answer can be obtained directly by running the list once;
I have to say that it is really clever to maintain with list;
AC code:

#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;
} 

Guess you like

Origin blog.csdn.net/qq_44555205/article/details/104555076