caioj1230: [图论补充]哈密顿路径

保存模版

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

int n,m,st,ed;
int len,a[510];
bool v[510],mp[510][510];
void reverse(int l,int r)
{
    while(l<r)
    {
        swap(a[l],a[r]);
        l++;r--;
    }
}
void expand()
{
    while(1)
    {
        bool bk=false;
        for(int i=1;i<=n;i++)
        {
            if(v[i]==false&&mp[ed][i]==true)
            {
                v[i]=true;a[++len]=i;ed=i;
                bk=true;break;
            }
        }
        if(bk==false)break;
    }
}
void hamilton()
{
    st=1;
    for(int i=1;i<=n;i++)
        if(mp[st][i]==true){ed=i;break;}
    v[st]=true;a[++len]=st;
    v[ed]=true;a[++len]=ed;
    
    while(1)
    {
        expand();
        reverse(1,len);swap(st,ed);
        expand();
        
        //若st,ed不相连,处理成相连 
        if(mp[st][ed]==false)
        {
            //在a[2]到a[len-1]中寻找两个相邻的且与st、ed同时相连的点(必存在)
            for(int i=2;i<len-1;i++)
            {
                if(mp[st][a[i+1]]==true&&mp[ed][a[i]]==true)
                {
                    reverse(i+1,len);//倒置a[i+1]到a[len] 
                    ed=a[len];break;
                } 
            }
        }
        if(len==n)return ;
        
        //若a元素不满n个,未被遍历过的点在a[]中寻找与其相连的点
        for(int y=1;y<=n;y++)
        {
            if(v[y]==false)
            {
                bool bk=false;
                for(int i=1;i<len;i++)
                {
                    if(mp[a[i]][y]==true)//相当于把a[i]~a[i+1]之间的连接断开,然后把a[i]和y连起来 
                    {
                        st=a[i+1];ed=y;
                        reverse(1,i);reverse(i+1,len);
                        v[y]=true;a[++len]=y;
                        bk=true;break;
                    }
                }
                if(bk==true)break;
            }
        }
    }
}
int main()
{
    scanf("%d%d",&n,&m);
        
    int x,y;
    memset(mp,false,sizeof(mp));
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        mp[x][y]=true;mp[y][x]=true;
    }
    
    len=0;memset(a,0,sizeof(a));
    memset(v,false,sizeof(v));
    hamilton();
    
    for(int i=1;i<len;i++)printf("%d ",a[i]);
    printf("%d\n",a[len]);
    return 0;
}

 

posted @ 2018-01-18 15:30  AKCqhzdy  阅读(271)  评论(0编辑  收藏  举报