题目链接:http://poj.org/problem?id=2438

本文链接:http://www.cnblogs.com/Ash-ly/p/5452615.html

题意:

  有2*N个小朋友要坐在一张圆桌上吃饭,但是每两个小朋友之间存在一种关系,即敌人或者朋友,然后需要让你安排一个座位次序,使得相邻的两个小朋友都不会是敌人.假设每个人最多有N-1个敌人.如果没有输出"No solution!".

思路:

  如果按照题意直接建图,每个点表示一个小朋友,小朋友之间的敌对关系表示两个点之间有边.问题是求小朋友围着桌子的座次就是求图中的一个环,但是要求这个环不能包含所给出的每条边,所有没给出的边却是可以用的,也就是说本题实际上是在上面建的图的反图上求解一个环,使得该环包含所有点.包含所有点的环一定是一条哈密顿回路,所以题目就是求所给图的反图上的一条哈密顿回路.

  题目中给了一个特殊条件,就是一共有2*N个小朋友,但是每个人最多有N-1个敌人,也就是说,每个小朋友可以选择坐在身边的小朋友数大于n + 1,这就意味着在建立的反图中,每个点的度数大于N+1,由Dirac定理可知,此图一定存在哈密顿回路,所以答案不会出现"No solution!",即直接构造哈密顿回路就可以了.

代码:

 #include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector> using namespace std;
typedef long long LL;
const int maxN = ; inline void reverse(int arv[maxN + ], int s, int t){
int temp;
while(s < t){
temp = arv[s];
arv[s] = arv[t];
arv[t] = temp;
s++;
t--;
}
} void Hamilton(int ans[maxN + ], bool map[maxN + ][maxN + ], int n){
int s = , t;
int ansi = ;
int i, j;
int w;
int temp;
bool visit[maxN + ] = {false};
for(i = ; i <= n; i++) if(map[s][i]) break;
t = i;
visit[s] = visit[t] = true;
ans[] = s;
ans[] = t;
while(true){
while(true){
for(i = ; i <= n; i++){
if(map[t][i] && !visit[i]){
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
w = ansi - ;
i = ;
reverse(ans, i, w);
temp = s;
s = t;
t = temp;
while(true){
for(i = ; i <= n; i++){
if(map[t][i] && !visit[i]){
ans[ansi++] = i;
visit[i] = true;
t = i;
break;
}
}
if(i > n) break;
}
if(!map[s][t]){
for(i = ; i < ansi - ; i++)
if(map[ans[i]][t] && map[s][ans[i + ]])break;
w = ansi - ;
i++;
t = ans[i];
reverse(ans, i, w);
}
if(ansi == n) return;
for(j = ; j <= n; j++){
if(visit[j]) continue;
for(i = ; i < ansi - ; i++)if(map[ans[i]][j])break;
if(map[ans[i]][j]) break;
}
s = ans[i - ];
t = j;
reverse(ans, , i - );
reverse(ans, i, ansi - );
ans[ansi++] = j;
visit[j] = true;
}
} int main(){
//freopen("input.txt", "r", stdin);
int N, M;
while(~scanf("%d%d", &N, &M) && (N || M)){
N *= ;
bool map[maxN + ][maxN + ] = {};
int ans[maxN + ] = {};
int ansi = ;
for(int i = ; i <= N; i++)
for(int j = ; j <= N; j++)
i == j ? map[i][j] = map[j][i] = : map[i][j] = map[j][i] = ;
memset(ans, , sizeof(ans));
for(int i = ; i <= M; i++){
int u, v;
scanf("%d%d", &u, &v);
map[u][v] = map[v][u]= ;
}
Hamilton(ans, map, N);
for(int i = ; i < N; i++)
printf(i == ? "%d":" %d", ans[i]);
printf("\n"); }
return ;
}

POJ 2438 Children's Dining(哈密顿回路)的更多相关文章

  1. poj 2438 Children's Dining

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

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

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

  3. POJ 2438 哈密顿回路

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

  4. POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

    POJ 3083 -- Children of the Candy Corn(DFS+BFS) 题意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 1)先输出左转优先时,从S到E的步数 ...

  5. POJ 2438 (哈密顿回路)

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

  6. poj 3083 Children of the Candy Corn

    点击打开链接 Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8288 ...

  7. poj 3083 Children of the Candy Corn(DFS+BFS)

    做了1天,总是各种错误,很无语 最后还是参考大神的方法 题目:http://poj.org/problem?id=3083 题意:从s到e找分别按照左侧优先和右侧优先的最短路径,和实际的最短路径 DF ...

  8. POJ 3083 Children of the Candy Corn bfs和dfs

      Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8102   Acc ...

  9. POJ:3083 Children of the Candy Corn(bfs+dfs)

    http://poj.org/problem?id=3083 Description The cornfield maze is a popular Halloween treat. Visitors ...

随机推荐

  1. 在Eclipse上使用egit插件通过ssh协议方式上传项目代码的具体步骤

    在Eclipse上使用egit插件通过ssh协议方式上传项目代码 前戏: 使用ssh方式可以不通过https协议,避免直接提供账号密码的方式上传项目到git在线服务器,如Bitbucket.GitHu ...

  2. share-Nothing原理

    Share nothing理论在数据库设计和优化中的实践应用 首先介绍share nothing概念.最早接触它是在 DataBaseManagentSystem一书的并行数据库章节中. 并行数据库要 ...

  3. STM32 启动代码 bootloader

    什么是启动代码?     启动代码是系统上电或者复位后运行的第一段代码,是进入C 语言的main 函数之前需要执行的那段汇编代码.STM32的启动代码在startup_stm32f10x_hd.s 启 ...

  4. VS2010 VC Project的default Include设置

    在IDE中,打开View->Other Windows->Property Manager.展开树形后,你会发现一个名为“Microsoft.Cpp.Win32.user”的项目(如下图) ...

  5. jwplayer 部署方案1

    <body> <div id="my_player" data_src="http://xx.com/jwplayer/uploads/test.mp4 ...

  6. 转:A Painless Q-learning Tutorial (一个 Q-learning 算法的简明教程)

    demo 参见 MDP DEMO   本文是对 http://mnemstudio.org/path-finding-q-learning-tutorial.htm 的翻译,共分两部分,第一部分为中文 ...

  7. 分布式缓存Memcache

    Memcached是分布式的,也就是说它不是本地的.它基于网络连接(当然它也可以使用localhost)方式完成服务,本身它是一个独立于应用的程序或守护进程(Daemon方式). Memcached使 ...

  8. 【洛谷 P2464】[SDOI2008]郁闷的小J(线段树)

    题目链接 这题我很久之前用分块写过,没写出来.. 今天又看到了,于是下决心把这题做出来. 这次我用线段树写的,直接对每本书的编号Hash一下然后离散化然后各建一棵线段树,维护当前编号在某个位置有没有书 ...

  9. bootstrap row 行间距

    <div class="clearfix" style="margin-bottom: 10px;"></div>清除浮动加个margi ...

  10. vue 数组、对象 深度拷贝和赋值

    由于此对象的引用类型指向的都是一个地址(除了基本类型跟null,对象之间的赋值,只是将地址指向同一个,而不是真正意义上的拷贝) 数组: let a = [11,22,33]; let b = a; / ...