hdu - 4337 - King Arthur's Knights - 哈密顿回路

/*
Pro: 0

Sol:设一个无向图中有 N 个节点,若所有节点的度数都大于等于 ( N + 1 )/2,
则汉密尔顿回路一定存在。

date:
*/
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
const int maxn=202*2;

int map[maxn][maxn];
int ans[maxn];
bool vis[maxn];
int n,m,s,t;
int ansi;
//ansi 必须是全局变量
void reverse(int ss, int tt){
    int cc;
    while(ss < tt){
        cc = ans[ss];
        ans[ss] = ans[tt];
        ans[tt] = cc;
        ss ++; tt --;   //不写这个会死循环哦
    }
}

void Hamilton(){
    int i, j, s  = 1 , t , tmp;     ansi = 2;
    memset(vis,0,sizeof(vis));      vis[s] = true;  ans[0] = s;

    for(i = 2; i <= n; i ++) if(map[s][i]) break;
    vis[i] = true; ans[1] = i; t = i;


    while(true){
        while(true){
            for(i = 1; i <= n; i ++){
                if(map[t][i] && !vis[i]){
                    vis[i] = true;
                    t = i;
                    ans[ansi ++] = i;
                    break;
                }
            }
            if(i > n) break;
        }
        reverse(0, ansi - 1);
        tmp = s, s = t, t = tmp;
        while(true){
            for(i = 1; i <= n; i ++){
                if(map[t][i] && !vis[i]){
                    vis[i] = true;
                    t = i;
                    ans[ansi ++] = i;
                    break;
                }
            }
            if(i > n) break;
        }

    /*到此时为找到一个最长的链*/
        if(!map[s][t])//若不能形成一个环,就让他形成一个环
            for(i = 1; i <= ansi - 2; i ++)
                if(map[ans[i + 1]][s] && map[ans[i]][t]) break;

        t = ans[ ++ i]; //  是ans[]里面存的东西
        reverse(i, ansi - 1);

    /*到此时已经形成一个环,就去找小尾巴*/
        if(ansi == n) {
//            cout << "ansii" << ansi << endl;
            return;
        }
        for(j = 1;j <= n;j ++){
            if(vis[j]) continue ;
            for(i = 1;i < ansi - 1;i ++) if(map[ans[i]][j]) break ;
            if(map[ans[i]][j]) break ;
        }
    //找到了小尾巴j,形成一条链
        vis[j] = true;  s = ans[i - 1], t = j;
        reverse(0, i - 1);  reverse(i, ansi - 1);
        ans[ansi ++] = j;
    //再重复以上过程
    }
}
int main(){
    while(scanf("%d%d",&n, &m) != EOF){
        if(n == 2){//这个挺好的
            cout << 1 << " " << 2<< endl;
            continue;
        }
        int a,b;
        memset(map,0,sizeof(map));
        for(int i = 0 ; i < m; i ++){
            scanf("%d%d",&a,&b);
            map[a][b] = map[b][a] = 1;
        }
        Hamilton();
        printf("%d",ans[0]);
//        cout << "@@@" << ansi << endl;
        for(int k = 1; k < ansi; k ++)
            printf(" %d",ans[k]);
        printf("\n");
    }
    return 0;
}

你可能感兴趣的:(hdu - 4337 - King Arthur's Knights - 哈密顿回路)