题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5424
解题思路:
题目大意:
给一个n个点,n-1条边的图,判定是否存在哈密顿路。
官方题解:
如果图是联通的,可以发现如果存在哈密顿路径,一定有一条哈密顿路径的一端是度数最小的点,从哪个点开始直接DFS搜索哈密顿路径复杂度是 O(n)的。要注意先判掉图不连通的情况。
算法思路:
如果存在哈密顿路,此时路径中含有n-1条边,剩下的那一条要么是自环(这里不予考虑,因为哈密顿路必然不经过),要么连接任意两个点。不考虑自环,此时图中的点度数为1的个数必然不超过2个,有如下三种情况:
1、剩下的那条边连接起点和终点,此时所有点度数都是2,可以从任意一个顶点开始进行DFS,看能否找到哈密顿路
2、剩下的那条边连接除起点和终点外的任意两个点,此时起点和终点度数为1,任选1个开始进行DFS。
3、剩下的那条边连接起点和除终点的任意一个点,或者连接终点与除起点外的任意一个点,此时图中仅有1个点度数为1,从该点开始进行DFS即可。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,cnt;
int deg[1005],Map[1005][1005];
bool flag,vis[1005];
void dfs(int u)
{
if(cnt == n){
flag = 1;
return;
}
for(int i = 1; i <=n && !flag; i++)
if(!vis[i] && Map[u][i])
{
vis[i] = 1;
cnt++;
dfs(i);
cnt--;
vis[i] = 0;
}
}
int main(){
while(~scanf("%d",&n)){
flag=0;
cnt=1;
memset(deg,0,sizeof(deg));
memset(vis,0,sizeof(vis));
memset(Map,0,sizeof(Map));
int x,y;
for(int i = 0; i < n; i++){
scanf("%d%d",&x,&y);
if(x != y && !Map[x][y]){
Map[x][y]=Map[y][x]=1;
deg[x]++;
deg[y]++;
}
}
int s = 1,tot = 0;
for(int i = 1; i <= n; i++)
if(deg[i] == 1){
s = i;
tot++;
}
if(tot > 2){
printf("NO\n");
continue;
}
vis[s] = 1;
dfs(s);
if(flag)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}