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

来源:互联网 发布:自动统计软件报价 编辑:程序博客网 时间:2024/04/28 07:59
/*Pro: 0Sol:设一个无向图中有 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;}

原创粉丝点击