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 }
时间: 2024-10-06 00:12:17

hdu 5424 回溯+并查集判断连通性的相关文章

nyoj 单词拼接(并查集判断连通性+欧拉路径)

这题还是比较难的. 首先建图方面,如果单纯的把单词作为点,能拼接的关系作为边,那么就是哈密顿图(每个点仅能走一次),难度比较大. 换一种思路,就是把每个单词看成一条有向边,由该单词的首字母指向尾字母. 那么这题便是欧拉图的问题了. 本质上采用的还是搜索,但是为了快速得到字典序最小的欧拉路径,首先要对单词集进行排序. 排完序后,用边集数组存图:再通过计算各点的出度与入度,同时判断基图(不考虑边的方向的图)的连通性,判断是否存在欧拉回路或欧拉通路. 如果存在欧拉回路,那么就从0开始搜索: 如果存在欧

【板+并查集判断连通性】并查集判断连通性

1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<string> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 10 using namespace std; 11 typedef long long ll;

HDU 1878 欧拉回路 (并查集+欧拉回路)

题目地址:HDU 1878 这个题要注意欧拉回路与欧拉通路的区别.在都保证连通性的前提下,欧拉回路要求每个点的度数都是偶数,而欧拉通路允许两个点的度数是奇数.所以这题用并查集判断连通性后判断下度数就可以了. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib

HDU Catch (二分图判断奇环+并查集判断联通)

Problem Description A thief is running away!We can consider the city where he locates as an undirected graph in which nodes stand for crosses and edges stand for streets. The crosses are labeled from 0 to N–1. The tricky thief starts his escaping fro

Hdu 2473(并查集删除操作) Junk-Mail Filter

有木有很吊 加强 加强版   啊  ,看了都不敢做了   ,后来先做了食物链这个我还是看过的,但还是A不掉,没明白神魔意思 ,总而言之,大牛的博客是个好东西,我就那么看了一下,还是不懂怎莫办啊,哎,就那样就A掉了....... 今天我们来谈一下这个并查集的删除操作,根据我对大牛的理解啊,这个并查集的删除操作并不是把原来的节点删除掉,而是用一个替身替掉,现在的这个点只是用作桥梁的作用,即是无用的,del  ,,,del  ,,,,删除,那些被删掉的就从n开始给他们一个地址,然后即如下代码所示 #i

HDU1558 - Segment set 并查集 + 判断线段相交

HDU1558 - Segment set: http://acm.hdu.edu.cn/showproblem.php?pid=1558 题目大意: 输入一些线段的端点坐标,若两线段相交,则把他们合并成一个集合,输入数据里会有k,问和k线段相交的线段的数目(包括自己) 思路: 每次输入一条线段,都从头扫描一次. 找出之前输入的线段里面,所有和其相交的线段,并且合并(合并用的是线段的ID). 就是: 并查集 + 判断线段相交 代码: #include <iostream> #include &

利用并查集判断一个无向图是否成树

hdu 1272 利用并查集方法,找到各点的根节点. 几点注意: 一.树:1.无环 2.根节点入度为0,其余入度为1 判断依据: 1.若两个点的根节点相同(这两个点是父子关系),则形成环. 2.若所有点中只有一个点的根节点是他本身,则根节点入度为0. 二. 1. 0 0 :空树也是一颗树. 1 #include<iostream> 2 #include<algorithm> 3 #define Max 100005 4 using namespace std; 5 6 int f[

HDOJ Ice_cream&#39;s world I 2120【并查集判断成环】

Ice_cream's world I Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 848    Accepted Submission(s): 494 Problem Description ice_cream's world is a rich country, it has many fertile lands. Today,

HDU 1272 简单并查集

小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24915    Accepted Submission(s): 7641 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双