题意:给定一个n个点n条边的无向图,判断是否存在哈密顿路径。
思路:先用并查集判断图是否连通,然后从度数最小的点开始回溯,看是否能找到一条哈密顿路径。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <set> 5 using namespace std; 6 7 const int INF = 999999; 8 const int N = 1001; 9 int f[N]; 10 int d[N]; 11 int head[N]; 12 bool visit[N]; 13 int n, e; 14 15 void init() 16 { 17 e = 0; 18 memset( d, 0, sizeof(d) ); 19 memset( head, -1, sizeof(head) ); 20 memset( visit, 0, sizeof(visit) ); 21 for ( int i = 1; i < N; i++ ) f[i] = i; 22 } 23 24 struct Edge 25 { 26 int v, next; 27 } edge[N << 1]; 28 29 void addEdge( int u, int v ) 30 { 31 edge[e].v = v; 32 edge[e].next = head[u]; 33 head[u] = e++; 34 } 35 36 int findf( int x ) 37 { 38 if ( f[x] != x ) f[x] = findf( f[x] ); 39 return f[x]; 40 } 41 42 bool union_set( int x, int y ) 43 { 44 x = findf(x), y = findf(y); 45 if ( x == y ) 46 { 47 return false; 48 } 49 else 50 { 51 f[x] = y; 52 return true; 53 } 54 } 55 56 bool dfs( int u, int cnt ) 57 { 58 if ( cnt == n ) return true; 59 for ( int i = head[u]; i != -1; i = edge[i].next ) 60 { 61 int v = edge[i].v; 62 if ( !visit[v] ) 63 { 64 visit[v] = 1; 65 if ( dfs( v, cnt + 1 ) ) return true; 66 visit[v] = 0; 67 } 68 } 69 return false; 70 } 71 72 int main () 73 { 74 while ( scanf("%d", &n) != EOF ) 75 { 76 init(); 77 int c = 0; 78 for ( int i = 1; i <= n; i++ ) 79 { 80 int u, v; 81 scanf("%d%d", &u, &v); 82 addEdge( u, v ); 83 addEdge( v, u ); 84 d[u]++, d[v]++; 85 if ( union_set( u, v ) ) c++; 86 } 87 if ( c != n - 1 ) 88 { 89 puts("NO"); 90 continue; 91 } 92 d[0] = INF; 93 int k = 0; 94 for ( int i = 1; i <= n; i++ ) 95 { 96 if ( d[i] < d[k] ) 97 { 98 k = i; 99 } 100 } 101 visit[k] = 1; 102 if ( dfs( k, 1 ) ) 103 { 104 puts("YES"); 105 } 106 else 107 { 108 puts("NO"); 109 } 110 } 111 return 0; 112 }
时间: 2024-10-06 00:12:17