Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them: Yuta has a non-direct graph with n vertices and n edges. Now he wants you to tell him if there exist a Hamiltonian path. It is too difficult for Rikka. Can you help her?
Input
There are no more than 100 testcases. For each testcase, the first line contains a number n(1≤n≤1000). Then n lines follow. Each line contains two numbers u,v(1≤u,v≤n) , which means there is an edge between u and v.
Output
For each testcase, if there exist a Hamiltonian path print "YES" , otherwise print "NO".
Sample Input
4 1 1 1 2 2 3 2 4 3 1 2 2 3 3 1
Sample Output
NO
YES
Hint For the second testcase, One of the path is 1->2->3 If you doesn't know what is Hamiltonian path, click here (https://en.wikipedia.org/wiki/Hamiltonian_path).
Source
给一个n条边,n个顶点的图,判定是否存在哈密顿路。
如果存在哈密顿路,此时路径中含有n-1条边,剩下的那一条要么是自环(这里不予考虑,因为哈密顿路必然不经过),要么连接任意两个点。不考虑自环,此时图中的点度数为1的个数必然不超过2个,有如下三种情况:
1、剩下的那条边连接起点和终点,此时所有点度数都是2,可以从任意一个顶点开始进行DFS,看能否找到哈密顿路
2、剩下的那条边连接除起点和终点外的任意两个点,此时起点和终点度数为1,任选1个开始进行DFS。
3、剩下的那条边连接起点和除终点的任意一个点,或者连接终点与除起点外的任意一个点,此时图中仅有1个点度数为1,从该点开始进行DFS即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 int map[1005][1005]; 6 int dgree[1005]; 7 int vis[1005]; 8 int n; 9 int f; 10 void dfs(int x) 11 { 12 vis[x]=1; 13 for(int i=1;i<=n;i++) 14 { 15 if(!vis[i] && map[x][i]) 16 { 17 dfs(i); 18 vis[i]=1; 19 } 20 } 21 } 22 void dfs1(int u,int num){ 23 if(num==n){ 24 f=1; 25 return; 26 } 27 for(int i=1;i<=n;i++){ 28 if(!vis[i] && map[u][i]){ 29 vis[i]=1; 30 dfs1(i,num+1); 31 if(f) 32 return; 33 vis[i]=0; 34 } 35 } 36 } 37 int main() 38 { 39 int t; 40 41 int x,y; 42 while(scanf("%d",&n)==1) 43 { 44 memset(vis,0,sizeof(vis)); 45 memset(map,0,sizeof(map)); 46 memset(dgree,0,sizeof(dgree)); 47 for(int i=0;i<n;i++) 48 { 49 scanf("%d%d",&x,&y); 50 map[x][y]=map[y][x]=1; 51 ++dgree[x]; 52 ++dgree[y]; 53 } 54 dfs(1); 55 int flag=1; 56 int count=0; 57 for(int i=1;i<=n;i++) 58 { 59 if(!vis[i]) 60 { 61 flag=0; 62 break; 63 } 64 if(dgree[i]==1) 65 { 66 count++; 67 } 68 } 69 if(flag==0 || count>2) 70 { 71 printf("NO\n"); 72 continue; 73 } 74 if(count==0) 75 { 76 printf("YES\n"); 77 } 78 else { 79 f=0; 80 for(int i=1;i<=n;i++){ 81 if(dgree[i]==1){ 82 memset(vis,0,sizeof(vis)); 83 vis[i]=1; 84 dfs1(i,1); 85 if(f) 86 break; 87 } 88 } 89 if(f) puts("YES"); 90 else puts("NO"); 91 } 92 93 } 94 return 0; 95 }