zoukankan      html  css  js  c++  java
  • hdu 5424 回溯+并查集判断连通性

    题意:给定一个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 }
  • 相关阅读:
    基础之实战猜年龄游戏
    基本运算符与if while详解:
    while循环练习:
    常量与格式化输出练习
    Flask基础(05)-->路由的基本定义
    Flask基础(04)-->相关配置参数
    Flask基础(03)-->创建第一个Flask程序
    Flask基础(02)-->搭建Flask项目虚拟环境
    Flask基础(01)-->Flask框架介绍
    Flask实战第61天:帖子板块过滤显示
  • 原文地址:https://www.cnblogs.com/huoxiayu/p/4772252.html
Copyright © 2011-2022 走看看