题目链接:传送门
分析(转自bestcoder):
如果图是联通的,可以发现如果存在哈密顿路径,一定有一条哈密顿路径的一端是度数最小的点,从哪个点开始直接DFS搜索哈密顿路径复杂度是 O(n)的。要注意先判掉图不连通的情况。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 1e3+10;
int degree[maxn];
bool vis[maxn];
vector<int >vc[maxn];
void init(){
for(int i=0;i<maxn;i++){
degree[i]=0;
vc[i].clear();
vis[i]=0;
}
}
int mp[maxn][maxn];
int n;
void dfs1(int u,int &num){
num++;
vis[u]=1;
for(int i=0;i<vc[u].size();i++){
int v = vc[u][i];
if(!vis[v])
dfs1(v,num);
}
}
bool dfs2(int u,int pre,int num){
vis[u]=1;
num++;
if(num==n) return 1;
for(int i=0;i<vc[u].size();i++){
int v = vc[u][i];
if(v!=pre&&!vis[v]){
if(dfs2(v,u,num))
return 1;
}
}
vis[u]=0;
return 0;
}
int main()
{
while(~scanf("%d",&n)){
init();
memset(mp,0,sizeof(mp));
for(int i=0;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
if(u==v||mp[u][v]) continue;
vc[u].push_back(v);
vc[v].push_back(u);
mp[u][v]=1;
mp[v][u]=1;
degree[u]++;
degree[v]++;
}
int num=0;
dfs1(1,num);
if(num!=n){
puts("NO");
continue;
}
int st=1,d=10000000;
for(int i=1;i<=n;i++){
if(degree[i]<d)
st=i,d=degree[i];
}
memset(vis,0,sizeof(vis));
if(dfs2(st,0,0)) puts("YES");
else puts("NO");
}
return 0;
}