题目链接: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. BZOJ4567 SCOI2016背单词(trie+贪心)

    倒过来变成查询前缀.考虑怎么排序.第一条代价n*n就相当于inf,说明一个单词的所有前缀都要排在它前面.那么串的依赖关系就是trie的结构.二三条说明代价是Σidi-idfa,那么显然最后的编号应该是 ...

  2. hihocoder 后缀自动机专题

    一.后缀自动机基本概念的理解 1.首先后缀自动机的状态是由子串的endpos来决定的 子串的endpos是指一个子串可以在原字符串的哪些位置进行匹配, endpos构成的不同集合划分成不同的状态 关于 ...

  3. 【南开OJ2264】节操大师(贪心+二分+并查集/平衡树)

    好久没更新了,今天就随便写一个吧 题目内容 MK和他的小伙伴们(共n人,且保证n为2的正整数幂)想要比试一下谁更有节操,于是他们组织了一场节操淘汰赛.他们的比赛规则简单而暴力:两人的节操正面相撞,碎的 ...

  4. bootstrap-table 增加序号列(支持分页)

    columns: [ { checkbox: true }, { title: '序号', align: 'center', halign: 'center', formatter: function ...

  5. [Leetcode] Add two numbers 两数之和

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  6. 【CF edu 30 A. Chores】

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...

  7. nc用法小记

    By francis_hao    Jun 30,2017   ncat:连接和重定向套接字 概要 ncat [OPTIONS...] [hostname] [port]   描述 ncat 是一个集 ...

  8. JAVA int自动装箱

    int 转 Integer: Integer int127_1 = 127; Integer int127_2 = 127; System.out.println("int127_1 == ...

  9. POJ2253:Frogger(改造Dijkstra)

    Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 64864   Accepted: 20127 题目链接:ht ...

  10. ireport写sql语句的按钮在哪