100851K King’s Inspection
题目大意
给你一张图,求这张图的汉密尔顿回路。
分析
因为m≤n+20,所以如果存在回路一定是在一个环中加入了至多20条边。我们先考虑dfs,但我们发现如果出现图1这种情况就会是复杂度爆炸
图1
图2
我们发现如果有很多这样的三角形程序就会爆炸。所以我们考虑优化。我们发现对于所有出度为1的点我们完全不必枚举它的出边,所以根据这些就写出了代码1,然后它居然能水过,但是对于像图2这种数据它就只有被卡掉的份啦,所以我们考虑继续优化。我们考虑将所有只有一条路径的点从图中真实的去掉,也就是说我们将所有点的相连关系提前记录下来,以便后续输出答案,而在搜索过程中只考虑出度不为1的点,听起来可能有些麻烦,参照代码2看看写写就好理解了。
代码1
#include<bits/stdc++.h>
using namespace std;
vector<int>v[];
int n,m,x[],y[],vis[],id[],od[],nxt[];
int ans[];
inline void bad(){
puts("There is no route, Karl!");
exit();
}
inline void dfs(int x){
if(vis[x])return;
vis[x]=;
for(int i=;i<v[x].size();i++)dfs(v[x][i]);
}
inline void pr(){
for(int i=;i<=n;i++)
printf(" %d",ans[i]);
puts("");
exit();
}
inline void search(int x,int cnt){
if(cnt==n){
ans[cnt]=x;
if(x==)pr();
return;
}
if(vis[x])return;
ans[cnt]=x;
vis[x]=;
if(nxt[x]){
search(nxt[x],cnt+);
}else {
for(int i=;i<v[x].size();i++){
search(v[x][i],cnt+);
}
}
vis[x]=;
return;
}
int main(){
freopen("king.in","r",stdin);
freopen("king.out","w",stdout);
scanf("%d%d",&n,&m);
if(m<n)bad();
for(int i=;i<=m;++i){
scanf("%d%d",&x[i],&y[i]);
v[x[i]].push_back(y[i]);
}
memset(vis,,sizeof(vis));
dfs();
for(int i=;i<=n;i++)
if(!vis[i])
bad();
for(int i=;i<=n;i++)v[i].clear();
for(int i=;i<=m;i++){
v[y[i]].push_back(x[i]);
}
memset(vis,,sizeof(vis));
dfs();
for(int i=;i<=n;i++)
if(!vis[i])
bad();
for(int i=;i<=n;i++)v[i].clear();
for(int i=;i<=m;i++){
v[x[i]].push_back(y[i]);
if(od[x[i]]==)od[x[i]]=y[i];
else if(od[x[i]]!=y[i])od[x[i]]=-;
if(id[y[i]]==)id[y[i]]=x[i];
else if(id[y[i]]!=x[i])id[y[i]]=-;
}
for(int i=;i<=n;i++)
if(od[i]==||id[i]==)
bad();
for(int i=;i<=n;i++)
if(od[i]>&&id[i]>){
nxt[i]=od[i];
nxt[id[i]]=i;
}
memset(vis,,sizeof(vis));
search(,);
bad();
return ;
}
代码2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define sp cout<<"---------------------------------------------------"<<endl
vector<int>v[];
vector<int>cpx;
int nxt[],vis[],arr[],n,m;
inline void bad(){
puts("There is no route, Karl!");
exit();
}
inline void check(){
int i,x;
memset(arr,,sizeof(arr));
for(i=,x=;i<=n;i++,x=nxt[x]){
if(arr[x])return;
arr[x]=;
}
for(i=,x=;i<=n;i++,x=nxt[x]){
printf("%d ",x);
}
cout<<<<endl;
exit();
}
inline void work(int wh){
if(wh==cpx.size()){
check();
return;
}
int x=cpx[wh];
for(int i=;i<v[x].size();i++)
if(!vis[v[x][i]]){
nxt[x]=v[x][i];
vis[v[x][i]]=;
work(wh+);
vis[v[x][i]]=;
}
return;
}
int main(){
freopen("king.in","r",stdin);
freopen("king.out","w",stdout);
int i,j,k;
scanf("%d%d",&n,&m);
for(i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
}
for(i=;i<=n;i++)
if(v[i].empty())bad();
for(i=;i<=n;i++)
if(v[i].size()>){
cpx.push_back(i);
}else {
if(vis[v[i][]])bad();
vis[v[i][]]=;
}
for(i=;i<=n;i++)
nxt[i]=v[i][];
work();
bad();
return ;
}
100851K King’s Inspection的更多相关文章
- Codeforces Gym 100851 K King's Inspection ( 哈密顿回路 && 模拟 )
题目链接 题意 : 给出 N 个点(最多 1e6 )和 M 条边 (最多 N + 20 条 )要你输出一条从 1 开始回到 1 的哈密顿回路路径,不存在则输出 " There is no r ...
- Gym 100851K
Problem King's Inspection 题目大意 给一张n个点m条边的无向图,问是否存在一条欧拉回路. n<=10^5, 0<=m<=n+20. 解题分析 注意到数据范围 ...
- NEERC15
2015-2016 ACM-ICPC Northeastern European Regional Contest 再开一个新坑吧 目前姿势有限,C.H.I仍然处于弃坑状态 代码戳这里 Problem ...
- Gym 100851 题解
A: Adjustment Office 题意:在一个n*n的矩阵,每个格子的的价值为 (x+y), 现在有操作取一行的值,或者一列的值之后输出这个和, 并且把这些格子上的值归0. 题解:模拟, 分成 ...
- 2019-2020 Saint-Petersburg Open High School Programming Contest (SpbKOSHP 19)
2019-2020 Saint-Petersburg Open High School Programming Contest (SpbKOSHP 19) easy: ABFGHI medium-ea ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- [bzoj1087][scoi2005]互不侵犯king
题目大意 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上 左下右上右下八个方向上附近的各一个格子,共8个格子. 思路 首先,搜索可以放弃,因为这是一 ...
- King's Quest —— POJ1904(ZOJ2470)Tarjan缩点
King's Quest Time Limit: 15000MS Memory Limit: 65536K Case Time Limit: 2000MS Description Once upon ...
- 【状压DP】bzoj1087 互不侵犯king
一.题目 Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上.下.左.右,以及左上.左下.右上.右下八个方向上附近的各一个格子,共8个格子. I ...
随机推荐
- webpack 单页面应用实战
这篇文章将介绍如何利用 webpack 进行单页面应用的开发,算是我在实际开发中的一些心得和体会,在这里给大家做一个分享.webpack 的介绍这里就不多说了,可以直接去官网查看. 关于这个单页面应用 ...
- touch: cannot touch '/usr/local/tomcat/logs/catalina.out': Permission denied解决方法
一.报以下错误: ./startup.sh Using CATALINA_BASE: /usr/local/tomcat702 Using CATALINA_HOME: /usr/local/tomc ...
- python中print的几种用法
python中的print有几种常用的用法: 1. print("first example") 2. print("second", "exampl ...
- python3 之logging模块
logging.getLogger(name=None)Return a logger with the specified name or, if name is None, return a lo ...
- Python:包、模块、类、函数的调用
一.关系 包一般指文件夹或者安装包(安装包一般也是压缩后的文件夹),里面包含多个.py文件(必须有一个__init__.py文件),一般也含有多个子包(或子文件夹): 一般一个.py文件就是一个模块, ...
- java继承实例基础
总结:多态.重写.构造方法调用 package com.a; public class fsd { int a = 23; public fsd() { System.out.println(4444 ...
- [机器学习基础]矩阵基础和numpy
矩阵定义:[摘自百度百科] 由 m × n 个数aij排成的m行n列的数表称为m行n列的矩阵,简称m × n矩阵.记作: 这m×n 个数称为矩阵A的元素,简称为元,数aij位于矩阵A的第i行第j列,称 ...
- Python打造一个目录扫描工具
目标:用Python3写一款小型的web目录扫描工具 功能:1.扫描指定站点 2.指定网站脚本类型来扫描 3.可控线程 4.可保存扫描结果 首先定义一个命令参数的函数 def parse_option ...
- 阿里云服务器ubuntu安装redis2.8.13
阿里云服务器ubuntu安装redis2.8.13 2014-09-04 16:14 | coding云 | 2198次阅读 | 暂无评论 一.下载redis 可以先下载到本地,然后ftp到服 ...
- LNMP 1.1 php编译安装
LNMP 是 Linux nginx mysql php nginx和apache一样也是一种web服务.在静态web服务中nginx更胜一筹.在动态中不比apache有优势. LNMP的mysql ...