POJ 2438 哈密顿回路
| Time Limit: 1000MS | Memory Limit: 65536K | |||
| Total Submissions: 4730 | Accepted: 754 | Special Judge | ||
Description
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
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
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 哈密顿回路的更多相关文章
- POJ 2438 Children's Dining(哈密顿回路)
题目链接:http://poj.org/problem?id=2438 本文链接:http://www.cnblogs.com/Ash-ly/p/5452615.html 题意: 有2*N个小朋友要坐 ...
- POJ 2438 (哈密顿回路)
分析: 2*n个小朋友,每个最多有n-1个"敌人",显然是存在哈密顿回路的. 预处理边,然后找哈密顿回路. code #include <iostream> #incl ...
- poj 2438 Children's Dining
http://poj.org/problem?id=2438 题意: 有2*N个人要坐在一张圆桌上吃饭,有的人之间存在敌对关系,安排一个座位次序,使得敌对的人不相邻. 假设每个人最多有N-1个敌人.如 ...
- POJ 2438 Children’s Dining (哈密顿图模板题之巧妙建反图 )
题目链接 Description Usually children in kindergarten like to quarrel with each other. This situation an ...
- Hamilton回路的判定与构造
定理1:在一个具有n个顶点的无向连通图G中,如果任意两个顶点的度数之和大于n,则G具有Hamilton回路.此条件为充分条件 定理2:设图G = <V,E>,是Hamilton图,则对于v ...
- Ouroboros Snake POJ - 1392(数位哈密顿回路)
看hdu 2894的题意 两个题一样 旋转鼓的表面分成m块扇形,如图所示(m=8).图中阴影区表示用导电材料制成,空白区用绝缘材料制成,终端a.b和c是3(k=3)处接地或不是接地分别用二进制信号0 ...
- POJ 3301 Texas Trip (三分)
题目链接 题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点.输出面积. 思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变. 正方形从 ...
- 【转】欧拉回路&特殊图下的哈密顿回路题集
转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...
- 【POJ】【1739】Tony's Tour
插头DP 楼教主男人八题之一! 要求从左下角走到右下角的哈密顿路径数量. 啊嘞,我只会求哈密顿回路啊……这可怎么搞…… 容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~ 我们可 ...
随机推荐
- JavaScript 在线测试
<iframe src="http://www.it1352.com/Onlinetools/OnlineCompileCommon/17?c_height=100&r_hei ...
- zabbix告警邮件、短信发送错误快速排查方法
zabbix告警邮件.短信发送错误快速排查方法 背景 zabbix告警邮件.短信经常有同事反馈发送错误的情况,这个问题排查的角度很多,那么最快捷的角度是什么呢? 在我看来,最快的角度就是判断这个告警邮 ...
- DLL动态库多次加载问题
原因涉及DLL加载和运行机制,主要有两点:1)DLL动态链接库无法独立运行,必须由一个应用程序进程加载到进程空间后才能使用.加载DLL的进程称为宿主进程.被加载的DLL属于宿主进程,不属于宿主进程内某 ...
- 第1节 flume:10、flume的更多组件介绍
作业:flume如何实现收集mysql的数据,没隔几秒钟,查看mysql中的数据是否有变化,一旦有变化,把数据拿过来,存到hdfs上. 需要使用custom source.可网上搜索,github上.
- net core 使用ef生成实体类(SqlServer)
1)打开程序包管理器控制台 2)输入命令 Install-Package Microsoft.EntityFrameworkCore.SqlServer 3)输入命令 Install-Packag ...
- 牛客OI赛制测试赛2 A 无序组数
链接:https://www.nowcoder.com/acm/contest/185/A来源:牛客网 题目描述 给出一个二元组(A,B) 求出无序二元组(a,b) 使得(a|A,b|B)的组数 无序 ...
- [LOJ] 分块九题 3
https://loj.ac/problem/6279 区间修改,区间查询前驱. TLE无数,我觉得这代码最精髓的就是block=1000. 谜一样的1000. 两个启示: 块内可以维护数据结构,比如 ...
- 用户管理命令--passwd,usermod,userdel
用户修改密码命令--passwd 当修改用户的密码时,也要分普通用户和超级用户两种情况 普通用户:修改密码前需要先输入当前密码,确认是否正确 密码设置不可以过于简单 超级用户:权利非常的大,可以设置任 ...
- LeetCode(169)Majority Element
题目 Given an array of size n, find the majority element. The majority element is the element that app ...
- 【C#】【数据结构】006-栈:链栈
C#数据结构:链栈 1.自定义链栈结构: 链栈节点类 using System.Collections; using System.Collections.Generic; using UnityEn ...