zoukankan      html  css  js  c++  java
  • 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
    ",a[len]);
        return 0;
    }
  • 相关阅读:
    java中的异常类
    Mysql--JDBC的基础
    eclipse使用断言
    idea中使用断言
    java的null
    array,集合(collection),集合(list)的区别
    命名管道FIFO
    标准库中的管道操作
    现代进程间的通信方式--管道
    广播编程之发送者
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8310497.html
Copyright © 2011-2022 走看看