您的位置:首页 > 其它

SGU 122 The book(哈密顿图)

2016-04-15 10:13 537 查看
Description

给出一个n个点的无向图,每个点的度数不小于[(n+1)/2],求一条从1开始的哈密顿回路

Input

第一行一个整数n表示点数,之后n行每行为一个点的邻接表

Output

输出一条从1开始的哈密顿回路,如果不存在就输出No solution

Sample Input

4

2 3

1 4

1 4

2 3

Sample Output

1 3 4 2 1

Solution

任意两个点的度数之和不小于n,这是哈密顿回路存在的充分条件,所以此题哈密顿回路必然存在,之后套模版求哈密顿回路即可

Code

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1111
int n,ans[maxn],vis[maxn];
bool M[maxn][maxn];
void reverse(int l,int r)
{
while(l<r)
{
swap(ans[l],ans[r]);
l++,r--;
}
}
void Hamilton()
{
int s=1,t,res=2,i,j;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
if(M[s][i])break;
t=i;
vis[s]=vis[t]=1;
ans[0]=s,ans[1]=t;
while(1)
{
while(1)
{
for(i=1;i<=n;i++)
if(M[t][i]&&!vis[i])
{
ans[res++]=i,vis[i]=1,t=i;
break;
}
if(i>n)break;
}
reverse(0,res-1);
swap(s,t);
while(1)
{
for(i=1;i<=n;i++)
if(M[t][i]&&!vis[i])
{
ans[res++]=i,vis[i]=1,t=i;
break;
}
if(i>n)break;
}
if(!M[s][t])
{
for(i=1;i<res-2;i++)
if(M[ans[i]][t]&&M[s][ans[i+1]])break;
t=ans[++i],reverse(i,res-1);
}
if(res==n)return ;
for(i=1;i<=n;i++)
{
if(vis[i])continue;
for(j=1;j<res-2;j++)if(M[ans[j]][i])break;
if(M[ans[j]][i])break;
}
s=ans[j-1],t=i;
reverse(0,j-1),reverse(j,res-1);
ans[res++]=i,vis[i]=1;
}
}
char s[3*maxn];
int main()
{
while(~scanf("%d",&n))
{
memset(M,0,sizeof(M));
getchar();
for(int j=1;j<=n;j++)
{
gets(s);
int len=strlen(s);
for(int i=0;i<len;i++)
{
int temp=0;
if(s[i]==' ')continue;
while(i<len&&s[i]>='0'&&s[i]<='9')
temp=temp*10+s[i]-'0',i++;
M[j][temp]=M[temp][j]=1;
}
}
Hamilton();
for(int i=0;i<n;i++)
if(ans[i]==1)
{
for(int j=i,k=0;k<n;j=(j+1)%n,k++)
printf("%d ",ans[j]);
printf("1\n");
break;
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: