POJ2438(哈密顿回路模板题)

转自:http://blog.csdn.net/yihuikang/article/details/7832201

就是经过无权图每一个节点且每个节点只能经过一次所形成的回路,

抄了一下大神的模板,理解学习中······

个人认为这个模板有如下限制:

1:无向图;

2:所有结点的度数必须大于或等于[n/2];

3:求出的是哈密顿回路,而不是哈密顿图;

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
int ans[600];
int cnt=0;
int n;
int m;
int T,S;
int mp[600][600];
bool vis[600]={0};
void _reverse(int l,int r)
{
    while(l<r)
    {
        swap(ans[l],ans[r]);
        l++,r--;
    }
}
void expand()
{
    for(;;)
    {
        bool flag=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&mp[T][i])
            {
                ans[cnt++]=i;
                T=i;
                vis[i]=1;
                flag=true;
                break;
            }
        }
        if(!flag)break;
    }
}
void hamiltun()
{
    memset(vis,false,sizeof(vis));
    S=1;
    for(T=2;T<=n;T++)
    {
        if(mp[S][T])break;
    }
    cnt=2;
    ans[0]=S;
    ans[1]=T;

    vis[S]=true;
    vis[T]=true;
    while(1)
    {
        expand();
        _reverse(0,cnt-1);
        swap(S,T);
        expand();
        int mid=0;
        if(!mp[S][T])
        {
            for(int i=1;i<cnt-2;i++)
            {
                if(mp[ans[i]][T]&&mp[ans[i+1]][S])
                {
                    mid=i+1;
                    break;
                }
            }
            _reverse(mid,cnt-1);
            T=ans[cnt-1];
        }
        if(cnt==n)break;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                int j;
                for(j=1;j<cnt-1;j++)
                {
                    if(mp[ans[j]][i])break;
                }
                if(mp[ans[j]][i])
                {
                    T=i;
                    mid=j;
                    break;
                }
            }
        }
        S=ans[mid-1];
        _reverse(0,mid-1);
        _reverse(mid,cnt-1);
        ans[cnt++]=T;
        vis[T]=true;
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0)break;
        n*=2;
        memset(mp,1,sizeof(mp));
        for(int i=1;i<=n;i++)
        {
            mp[i][i]=0;
        }
        for(int i=1;i<=m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            mp[a][b]=0;
            mp[b][a]=0;
        }
        hamiltun();
        printf("%d",ans[0]);
        for(int i=1;i<=n-1;i++)
        {
            printf(" %d",ans[i]);
        }
        printf("\n");
    }
}


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页