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 ...
随机推荐
- 201621123014《Java程序设计》第十三周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
- Project://Meeting_Room
models from django.db import models from django.contrib.auth.models import AbstractUser class UserIn ...
- spring学习-2
Spring_属性配置细节 1.若字面值包含特殊字符,可以使用<[CDATA[]]>把字面值包裹起来 例:<value><![CDATA[<3333>^]]& ...
- Image Pyramid
今天我们介绍图像处理邻域中比较常用的一种方法,image pyramid, 也叫图像金字塔.就是将图像进行一层一层的下采样,图像金字塔是为了构建图像的多尺度,让模型能够更好的适应图像的尺度变化,图像金 ...
- tensorflow 学习笔记-1
http://www.jianshu.com/p/e112012a4b2d 参考的网站 -------------------------------------------------------- ...
- Spring通过XML方式实现定时任务
package com.wisezone.service; import java.text.SimpleDateFormat; import java.util.Date; import org.s ...
- IntelliJ IDEA 12创建Maven管理的Java Web项目(图解)
转:http://blog.csdn.net/zht666/article/details/8673609/ 本文主要使用图解介绍了使用IntelliJIDEA 12创建Maven管理的JavaWeb ...
- Python 中的几种矩阵乘法 np.dot, np.multiply, *
使用array时,运算符 * 用于计算数量积(点乘),函数 dot() 用于计算矢量积(叉乘).使用matrix时,运算符 * 用于计算矢量积,函数 multiply() 用于计算数量积. 下面是使用 ...
- LeetCode Judge Route Circle
原题链接在这里:https://leetcode.com/problems/judge-route-circle/description/ 题目: Initially, there is a Robo ...
- 【LeetCode】029. Divide Two Integers
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...