题目链接: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. C# 获取ORACLE SYS.XMLTYPE "遇到不支持的 Oracle 数据类型 USERDEFINED"

    1.需要加函数 2.需要加表别名 select   a.XML.getclobval()  from TB1  a

  2. 【题解】NOI2017游戏

    2-SAT.洛谷P3845 一开始以为——怎么有3个呢?后来发现因为每个地图都有一种车是不能用的,所以就等于每一个地图都有两个适应的车啦. 那么对于x类型的地图呢——只有8个,直接2^8暴力枚举每一种 ...

  3. C++——继承时的this指针

    1.this指针只在类的成员函数中使用,当类的成员函数需要用到自己的指针时就要用到this指针.但静态函数不能使用this关键字,其解释是:因为this是个引用,哪个对象调用方法就引用哪个对象. 而静 ...

  4. clientWidth、clientHeight、offsetWidth、offsetHeight以及scrollWidth、scrollHeight

    clientWidth.clientHeight.offsetWidth.offsetHeight以及scrollWidth.scrollHeight是几个困惑了好久的元素属性,趁着有时间整理一下 1 ...

  5. 【BZOJ 1485】[HNOI2009]有趣的数列 卡特兰数

    这个题我是冲着卡特兰数来的所以就没有想到什么dp,当然也没有想到用卡特兰数的原因........... 你只要求出前几项就会发现是个卡特兰数,为什么呢:我们选择地时候要选择奇数位和偶数位,相邻(一对里 ...

  6. vue中使用 echarts3.0 或 echarts2.0 (模拟迁徙图,折线图)

    一.echarts3.0(官网: http://echarts.baidu.com/) 首先通过npm安装echarts依赖,安装的为3.0版本 npm install echarts -s 也可以使 ...

  7. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  8. POJ2516:Minimum Cost(最小费用最大流)

    Minimum Cost Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 19088   Accepted: 6740 题目链 ...

  9. 安卓下拉刷新空间SwipeRefreshLayout的基本使用

    1.先写布局文件 <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/refresh" androi ...

  10. PHP设计模式-工厂模式、单例模式、注册模式

    本文参考慕课网<大话PHP设计模式>-第五章内容编写,视频路径为:http://www.imooc.com/video/4876 推荐阅读我之前的文章:php的设计模式 三种基本设计模式, ...