Children's Dining
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 4730   Accepted: 754   Special Judge

Description

Usually children in kindergarten like to quarrel with each other. This situation annoys the child-care women. For instant, when diner time comes, a fierce conflict may break out when a certain couple of children sitting side by side who are hostile with each other. Although there aren't too many children dining at the same round table, but the relationship of "enemy" or "friend" may be very complex. The child-care women do come across a big problem. Now it is time for you to help them to figure out a proper arrangement of sitting, with which no two "enemy" children is adjacent.

Now we assume that there are 2 * n children who sit around a big table, and that none has more than n - 1 "enemies".

Input

The input is consisted of several test blocks. For each block, the first line contains two integers n and m (1 <= n <= 200, 0 <= m <= n (n - 1)). We use positive integers from 1 to 2 * n to label the children dining round table. Then m lines followed. Each contains positive integers i and j ( i is not equal to j, 1 <= i, j <= 2 * n), which indicate that child i and child j consider each other as "enemy". In a input block, a same relationship isn't given more than once, which means that if "i j" has been given, "j i" will not be given.

There will be a blank line between input blocks. And m = n = 0 indicates the end of input and this case shouldn't be processed.

Output

For each test block, if the proper arrangement exist, you should print a line with a proper one; otherwise, print a line with "No solution!".

Sample Input

1 0

2 2
1 2
3 4 3 6
1 2
1 3
2 4
3 5
4 6
5 6 4 12
1 2
1 3
1 4
2 5
2 6
3 7
3 8
4 8
4 7
5 6
5 7
6 8 0 0

Sample Output

1 2
4 2 3 1
1 6 3 2 5 4
1 6 7 2 3 4 5 8

解析 题目说保证 每个点的度数等于n所以 一定存在哈密顿回路 然后在他给出的图的补图上求一个哈密顿回路就可以了 套一个O(n*n)的板子。

哈密顿图:存在哈密顿回路的图

哈密顿图的判定:

一:Dirac定理(充分条件)

  设一个无向图中有N个顶点,若所有顶点的度数大于等于N/2,则哈密顿回路一定存在.(N/2指的是⌈N/2⌉,向上取整)

二:基本的必要条件

  设图G=<V, E>是哈密顿图,则对于v的任意一个非空子集S,若以|S|表示S中元素的数目,G-S表示G中删除了S中的点以及这些点所关联的边后得到的子图,则W(G-S)<=|S|成立.其中W(G-S)是G-S中联通分支数.

三:竞赛图(哈密顿通路)

  N(N>=2)阶竞赛图一点存在哈密顿通路.

AC代码

 #include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = +;
bool visit[maxn];
int mapp[maxn][maxn],ans[maxn];
int n,m;
inline void _reverse(int s, int t) //将数组anv从下标s到t的部分的顺序反向
{
int temp;
while(s < t)
{
temp = ans[s];
ans[s] = ans[t];
ans[t] = temp;
s++;
t--;
}
}
void Hamilton(int n)
{
memset(visit,false,sizeof(visit));
int s = , t;//初始化取s为1号点
int ansi = ;
int i, j;
int w;
int temp;
for(i = ; i <= n; i++) if(mapp[s][i]) break;
t = i;//取任意邻接与s的点为t
visit[s] = visit[t] = true;
ans[] = s;
ans[] = t;
while(true)
{
while(true) //从t向外扩展
{
for(i = ; i <= n; i++)
{
if(mapp[t][i] && !visit[i])
{
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
w = ansi - ;//将当前得到的序列倒置,s和t互换,从t继续扩展,相当于在原来的序列上从s向外扩展
i = ;
_reverse(i, w);
temp = s;
s = t;
t = temp;
while(true) //从新的t继续向外扩展,相当于在原来的序列上从s向外扩展
{
for(i = ; i <= n; i++)
{
if(mapp[t][i] && !visit[i])
{
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
if(!mapp[s][t]) //如果s和t不相邻,进行调整
{
for(i = ; i < ansi - ; i++)//取序列中的一点i,使得ans[i]与t相连,并且ans[i+1]与s相连
if(mapp[ans[i]][t] && mapp[s][ans[i + ]])break;
w = ansi - ;
i++;
t = ans[i];
_reverse(i, w);//将从ans[i +1]到t部分的ans[]倒置
}//此时s和t相连
if(ansi == n) return;//如果当前序列包含n个元素,算法结束
for(j = ; j <= n; j++) //当前序列中元素的个数小于n,寻找点ans[i],使得ans[i]与ans[]外的一个点相连
{
if(visit[j]) continue;
for(i = ; i < ansi - ; i++)if(mapp[ans[i]][j])break;
if(mapp[ans[i]][j]) break;
}
s = ans[i - ];
t = j;//将新找到的点j赋给t
_reverse(, i - );//将ans[]中s到ans[i-1]的部分倒置
_reverse(i, ansi - );//将ans[]中ans[i]到t的部分倒置
ans[ansi++] = j;//将点j加入到ans[]尾部
visit[j] = true;
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n==)break;
n*=;
memset(mapp,,sizeof(mapp));
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
mapp[i][j]=i==j?:;
for(int i=;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
mapp[u][v]=mapp[v][u]=;
}
Hamilton(n);
printf("%d",ans[]);
for(int i=;i<=n-;i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
}

该算法的详细过程及哈密顿回路的其他知识

https://www.cnblogs.com/Ash-ly/p/5452580.html

POJ 2438 哈密顿回路的更多相关文章

  1. POJ 2438 Children's Dining(哈密顿回路)

    题目链接:http://poj.org/problem?id=2438 本文链接:http://www.cnblogs.com/Ash-ly/p/5452615.html 题意: 有2*N个小朋友要坐 ...

  2. POJ 2438 (哈密顿回路)

    分析: 2*n个小朋友,每个最多有n-1个"敌人",显然是存在哈密顿回路的. 预处理边,然后找哈密顿回路. code #include <iostream> #incl ...

  3. poj 2438 Children's Dining

    http://poj.org/problem?id=2438 题意: 有2*N个人要坐在一张圆桌上吃饭,有的人之间存在敌对关系,安排一个座位次序,使得敌对的人不相邻. 假设每个人最多有N-1个敌人.如 ...

  4. POJ 2438 Children’s Dining (哈密顿图模板题之巧妙建反图 )

    题目链接 Description Usually children in kindergarten like to quarrel with each other. This situation an ...

  5. Hamilton回路的判定与构造

    定理1:在一个具有n个顶点的无向连通图G中,如果任意两个顶点的度数之和大于n,则G具有Hamilton回路.此条件为充分条件 定理2:设图G = <V,E>,是Hamilton图,则对于v ...

  6. Ouroboros Snake POJ - 1392(数位哈密顿回路)

    看hdu 2894的题意  两个题一样 旋转鼓的表面分成m块扇形,如图所示(m=8).图中阴影区表示用导电材料制成,空白区用绝缘材料制成,终端a.b和c是3(k=3)处接地或不是接地分别用二进制信号0 ...

  7. POJ 3301 Texas Trip (三分)

    题目链接 题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点.输出面积. 思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变. 正方形从 ...

  8. 【转】欧拉回路&特殊图下的哈密顿回路题集

    转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...

  9. 【POJ】【1739】Tony's Tour

    插头DP 楼教主男人八题之一! 要求从左下角走到右下角的哈密顿路径数量. 啊嘞,我只会求哈密顿回路啊……这可怎么搞…… 容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~ 我们可 ...

随机推荐

  1. PL/SQL学习笔记(三)

    -----创建一个序列,再创建一个表(主键是数字),通过序列生成该表的主键值. create table mytb1( m_id number primary key, m_name ) not nu ...

  2. 编译安装LAMP之php(fpm模块)

    一,准备工作实验平台为CentOS6.6,先下载所需的安装包,我使用的是php-5.4.26.tar.gz,下载地址 http://mirrors.sohu.com/php/ 编译安装的目录:/usr ...

  3. [Java 8] (9) Lambda表达式对递归的优化(下) - 使用备忘录模式(Memoization Pattern) .

    使用备忘录模式(Memoization Pattern)提高性能 这个模式说白了,就是将需要进行大量计算的结果缓存起来,然后在下次需要的时候直接取得就好了.因此,底层只需要使用一个Map就够了. 但是 ...

  4. 使用python书写的小说爬虫

    1.写了一个简单的网络爬虫 初期1 (后期将会继续完善) #小说的爬取 import requests import random from bs4 import BeautifulSoup base ...

  5. python编码的初识

    用途: ​ 密码本:二进制 与 文字的对应关系 ASCII: ​ 最早的密码本:二进制与 英文字母,数字,特殊字符的对应关系 格式: 01100001 a 01100010 b 字节数: ​ 英文1个 ...

  6. 快速安装zabbix

    环境:CentOS 7.x 数据库mysql已事先安装 1.配置epel源 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/r ...

  7. 【JDBC】java连接MySQL数据库步骤

    java连接数据库步骤 1. 加载驱动 Class.forName("com.mysql.java.Driver"); 或: registerDriver(new com.mysq ...

  8. 如何用纯 CSS 创作一个荧光脉冲 loader 特效

    效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/erRzzR 可交互视频教程 此视 ...

  9. [Noip2004][Day ?][T?]合并果子(?.cpp)

    题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...

  10. luogu2633 Count on a tree

    主席树放到树上而已 #include <algorithm> #include <iostream> #include <cstdio> using namespa ...