题目大意:给出一张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; }