题目大意:给出一张n个点n条边的无向图,判断这张图中是否存在哈密顿通路。
分析:存在哈密顿通路:这张图要连通,有一条通路经过每个点一次。
dfs的时候每次只能从点x向一个未访问过的点y走,不能再由y回溯到x走x的其它相邻点,保证只经过每个点一次。
所以dfs是在循环外调用的。
为了优化,每次取x相邻的未访问过的度数最小的点扩展。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
struct node{
int y,next;
}edge[1010];
int n,l,u,v,m,s;
int head[1010],d[1010];
bool vis[1010];
void add(int x,int y)
{
l++;
edge[l].y=y;
edge[l].next=head[x];
head[x]=l;
}
void dfs(int x)
{
vis[x]=1;
m++;
int p=head[x];
int y=-1;
while (p)
{
if (!vis[edge[p].y])
if (y==-1||d[y]>d[edge[p].y]) y=edge[p].y;//找度最小的一个点——优化
p=edge[p].next;
}
if (~y) dfs(y);//求哈密顿回路的时候每次只能从一个点走到另外一个点,保证每个点只遍历一边
//在循环外dfs,不会走到其他支路上
}
int main()
{
while (cin>>n)
{
memset(d,0,sizeof(d));
l=0;
memset(head,0,sizeof(head));
for (int i=1;i<=n;i++)
{
cin>>u>>v;
add(u,v);
add(v,u);
d[u]++;d[v]++;
}
s=1;
for (int i=1;i<=n;i++)
if (d[s]>d[i]) s=i;//好神奇的找最小方式
m=0;
memset(vis,0,sizeof(vis));
dfs(s);
if (m==n) cout<<"YES"<<endl; else cout<<"NO"<<endl;
//m<n时包含了图不连通和没有哈密顿回路的情况
}
return 0;
}