您的位置:首页 > 其它

hdu 5424 回溯+并查集判断连通性

2015-08-31 09:21 369 查看
题意:给定一个n个点n条边的无向图,判断是否存在哈密顿路径。

思路:先用并查集判断图是否连通,然后从度数最小的点开始回溯,看是否能找到一条哈密顿路径。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <set>
using namespace std;

const int INF = 999999;
const int N = 1001;
int f
;
int d
;
int head
;
bool visit
;
int n, e;

void init()
{
e = 0;
memset( d, 0, sizeof(d) );
memset( head, -1, sizeof(head) );
memset( visit, 0, sizeof(visit) );
for ( int i = 1; i < N; i++ ) f[i] = i;
}

struct Edge
{
int v, next;
} edge[N << 1];

void addEdge( int u, int v )
{
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}

int findf( int x )
{
if ( f[x] != x ) f[x] = findf( f[x] );
return f[x];
}

bool union_set( int x, int y )
{
x = findf(x), y = findf(y);
if ( x == y )
{
return false;
}
else
{
f[x] = y;
return true;
}
}

bool dfs( int u, int cnt )
{
if ( cnt == n ) return true;
for ( int i = head[u]; i != -1; i = edge[i].next )
{
int v = edge[i].v;
if ( !visit[v] )
{
visit[v] = 1;
if ( dfs( v, cnt + 1 ) ) return true;
visit[v] = 0;
}
}
return false;
}

int main ()
{
while ( scanf("%d", &n) != EOF )
{
init();
int c = 0;
for ( int i = 1; i <= n; i++ )
{
int u, v;
scanf("%d%d", &u, &v);
addEdge( u, v );
addEdge( v, u );
d[u]++, d[v]++;
if ( union_set( u, v ) ) c++;
}
if ( c != n - 1 )
{
puts("NO");
continue;
}
d[0] = INF;
int k = 0;
for ( int i = 1; i <= n; i++ )
{
if ( d[i] < d[k] )
{
k = i;
}
}
visit[k] = 1;
if ( dfs( k, 1 ) )
{
puts("YES");
}
else
{
puts("NO");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: