java 实现哈密顿通路算法_HDU 5424——Rikka with Graph II——————【哈密顿路径】...

Rikka with Graph II

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1051    Accepted Submission(s): 266

Problem Description

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has a non-direct graph with n vertices and n edges. Now he wants you to tell him if there exist a Hamiltonian path.

It is too difficult for Rikka. Can you help her?

Input

There are no more than 100 testcases.

For each testcase, the first line contains a number n(1≤n≤1000).

Then n lines follow. Each line contains two numbers u,v(1≤u,v≤n) , which means there is an edge between u and v.

Output

For each testcase, if there exist a Hamiltonian path print "YES" , otherwise print "NO".

Sample Input

4

1 1

1 2

2 3

2 4

3

1 2

2 3

3 1

Sample Output

NO

YES

Hint

For the second testcase, One of the path is 1->2->3

If you doesn't know what is Hamiltonian path, click here (https://en.wikipedia.org/wiki/Hamiltonian_path).

Source

题目大意:就给你n个顶点,n条边,问你是不是可以在图中找到哈密顿路径。

解题思路:对于n条边的图,如果要形成哈密顿路径,则必然要用掉n-1条边,形成一条链,起点和终点的度为1,其余点的度为2。剩下的一条边,可能有下面的情况:

情况1:形成自环,自环对于哈密顿路径没影响,可以忽略。

情况2:形成重边,重边对于哈密顿路径也没影响,可以忽略。

情况3:起点或终点跟非终点或非起点连一条边,这时候从终点或起点dfs。

情况4:起点跟终点连边,所有点的度都为2,从任意点dfs。

吐糟:自己写的时候vector清空的时候放在了最后,因为中间有continue,结果就呵呵了。。。一直超时,纳闷死了。再者就是没有考虑清楚,开始写的时候没有把所有路径都走完,会漏掉情况,不该呀~~~

#include

using namespace std;

const int maxn=2100;

const int INF=0x3f3f3f3f;

int degree[maxn];

int vis[maxn],gra[maxn][maxn];

vectorG[maxn];

int n;

bool dfs(int u,int fa,int cn){

if(cn==n){

return true;

}

for(int i=0;i

int v=G[u][i];

if(vis[v]||v==fa){

continue;

}

vis[v]=1;

if(dfs(v,u,cn+1))

return true;

vis[v]=0; //如果没有这句,会过不了这个样例。5 2 3 2 4 4 1 1 2 5 4

}

return false;

}

void init(){//以后尽量放在前面情况,不装B

for(int i=0;i<=n+2;i++)

G[i].clear();

memset(degree,0,sizeof(degree));

memset(vis,0,sizeof(vis));

memset(gra,0,sizeof(gra));

}

int main(){

int a,b;

while(scanf("%d",&n)!=EOF){

init();

for(int i=0;i

scanf("%d%d",&a,&b);

if(gra[a][b]==1||a==b)

continue;

gra[a][b]=gra[b][a]=1;

G[a].push_back(b);

G[b].push_back(a);

degree[a]++,degree[b]++;

}

int deg1=0,idx=1;

for(int i=1;i<=n;i++){

if(degree[i]==1){

deg1++;

idx=i;

}

}

if(deg1>2){ //度为1的大于2个,必然不行

puts("NO");

continue;

}

vis[idx]=1;

if(dfs(idx,0,1))

puts("YES");

else puts("NO");

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值