[NOIp2018提高组]旅行
[NOIp2018提高组]旅行:
题目大意:
一个\(n(n\le5000)\)个点,\(m(m\le n)\)条边的连通图。可以从任意一个点出发,前往任意一个相邻的未访问的结点,或沿着第一次来这个点的边返回。需要遍历每一个点。没经过一个新的结点,就将这个结点写下来。最终可以得到一个序列。求字典序最小的序列。
思路:
对于树的情况,显然从\(1\)出发,每次从字典序最小的相邻结点DFS即可。
对于有环的情况,由于环只有一个,我们可以将环找出来,枚举删掉环上的每一条边,然后按树的情况求解即可。
时间复杂度\(\mathcal O(n^2)\)。
源代码:
#include<set>
#include<stack>
#include<cstdio>
#include<cctype>
#include<vector>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=5001;
struct Edge {
int u,v;
};
Edge edge[N];
std::vector<std::pair<int,int> > g[N];
bool vis[N],mark[N];
std::stack<std::pair<int,int> > stk;
void dfs(const int &x,const int &par) {
vis[x]=true;
for(unsigned i=0;i<g[x].size();i++) {
const int &y=g[x][i].first;
if(y==par) continue;
stk.push(std::make_pair(x,g[x][i].second));
if(!vis[y]) {
dfs(y,x);
} else {
int z;
do {
z=stk.top().first;
mark[stk.top().second]=true;
stk.pop();
} while(z!=y);
throw 0;
}
stk.pop();
}
}
std::set<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].insert(v);
e[v].insert(u);
}
inline void del_edge(const int &u,const int &v) {
e[u].erase(v);
e[v].erase(u);
}
int s[N],ans[N];
void solve(const int &x,const int &par) {
s[++s[0]]=x;
for(std::set<int>::iterator i=e[x].begin();i!=e[x].end();i++) {
const int &y=*i;
if(y==par) continue;
solve(y,x);
}
}
inline bool check(int a[],int b[],const int &n) {
for(register int i=1;i<=n;i++) {
if(a[i]<b[i]) return true;
if(a[i]>b[i]) return false;
}
return false;
}
int main() {
const int n=getint(),m=getint();
for(register int i=0;i<m;i++) {
const int &u=edge[i].u=getint();
const int &v=edge[i].v=getint();
g[u].push_back(std::make_pair(v,i));
g[v].push_back(std::make_pair(u,i));
}
for(register int i=0;i<m;i++) {
add_edge(edge[i].u,edge[i].v);
}
if(m==n-1) {
solve(1,0);
for(register int i=1;i<=n;i++) {
printf("%d%c",s[i]," \n"[i==n]);
}
return 0;
}
try {
dfs(1,0);
} catch(...) {}
std::fill(&ans[1],&ans[n]+1,INT_MAX);
for(register int i=0;i<m;i++) {
if(!mark[i]) continue;
del_edge(edge[i].u,edge[i].v);
s[0]=0;
solve(1,0);
if(check(s,ans,n)) {
std::copy(&s[1],&s[n]+1,&ans[1]);
}
add_edge(edge[i].u,edge[i].v);
}
for(register int i=1;i<=n;i++) {
printf("%d%c",ans[i]," \n"[i==n]);
}
return 0;
}
[NOIp2018提高组]旅行的更多相关文章
- [NOIP2018 提高组] 旅行
考虑如果我们要回溯的话,一定要把非环上的子树都搜索完. 而在环上的一个地方回溯,相当于把环上的下一个点置于所有环的顺序的最后. 所以我们只有在环上遇到环上的最大点时且周围的点都比这个点小时非正常回溯即 ...
- [NOIp2018提高组]赛道修建
[NOIp2018提高组]赛道修建 题目大意: 给你一棵\(n(n\le5\times10^4)\)个结点的树,从中找出\(m\)个没有公共边的路径,使得第\(m\)长的路径最长.问第\(m\)长的路 ...
- [NOIp2018提高组]货币系统
[NOIp2018提高组]货币系统 题目大意: 有\(n(n\le100)\)种不同的货币,每种货币的面额为\([1,25000]\)之间的一个整数.若两种货币系统能够组合出来的数是相同的的,那我们就 ...
- [NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路
[NOIp2013提高组]积木大赛/[NOIp2018提高组]铺设道路 题目大意: 对于长度为\(n(n\le10^5)\)的非负数列\(A\),每次可以选取一个区间\(-1\).问将数列清零至少需要 ...
- NOIP2018提高组省一冲奖班模测训练(六)
NOIP2018提高组省一冲奖班模测训练(六) https://www.51nod.com/Contest/ContestDescription.html#!#contestId=80 20分钟AC掉 ...
- NOIP2018提高组省一冲奖班模测训练(五)
NOIP2018提高组省一冲奖班模测训练(五) http://www.51nod.com/Contest/ContestDescription.html#!#contestId=79 今天有点浪…… ...
- NOIP2018提高组金牌训练营——动态规划专题
NOIP2018提高组金牌训练营——动态规划专题 https://www.51nod.com/Live/LiveDescription.html#!#liveId=19 多重背包 二进制优化转化成01 ...
- NOIP2018提高组省一冲奖班模测训练(四)
NOIP2018提高组省一冲奖班模测训练(四) 这次比赛只AC了第一题,而且花了40多分钟,貌似是A掉第一题里面最晚的 而且还有一个半小时我就放弃了…… 下次即使想不出也要坚持到最后 第二题没思路 第 ...
- NOIP2018提高组省一冲奖班模测训练(三)
NOIP2018提高组省一冲奖班模测训练(三) 自己按照noip的方式考,只在最后一两分钟交了一次 第一题过了,对拍拍到尾. 第二题不会.考试时往组合计数的方向想,推公式,推了一个多小时,大脑爆炸,还 ...
随机推荐
- 20165206 2017-2018-2 《Java程序设计》第七周学习总结
20165206 2017-2018-2 <Java程序设计>第七周学习总结 教材学习内容总结 MySqL:是世界上最流行的开源数据管理系统. 配置启动MySQL. 连接数据库:Conne ...
- 微信jssdk分享功能开发
先理解下分享: 在app端 ,经常能看见 分享按钮的功能,(分享给朋友,分享到朋友圈,分享到QQ空间等等): https://open.weixin.qq.com/(微信开发平台),这需要到开放平台注 ...
- SQL Server Profiler的简单使用
SQL Server Profiler可以检测在数据上执行的语句,特别是有的项目不直接使用sql语句,直接使用ORM框架的系统处理数据库的项目,在调试sql语句时,给了很大的帮助. 之前写了使用SQL ...
- Tomcat8 启动慢 Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [53,161] milliseconds
修改$JAVA_PATH/jre/lib/security/java.security文件 将 securerandom.source=file:/dev/random 修改为 securerando ...
- C# 5.0 CallerMemberName CallerFilePath CallerLineNumber获取调用方法名称,路径,行号
class Program { static void Main(string[] args) { Log("测试"); Console.Read(); } public stat ...
- Spring MVC基础知识整理➣Spring+SpringMVC+Hibernate整合操作数据库
概述 Hibernate是一款优秀的ORM框架,能够连接并操作数据库,包括保存和修改数据.Spring MVC是Java的web框架,能够将Hibernate集成进去,完成数据的CRUD.Hibern ...
- error C1128: 节数超过对象文件格式限制: 请使用 /bigobj 进行编译
VS2015出现如上错误. 默认情况下,对象文件最多可存放 65,536 (2^16) 个可寻址的节. 这种情况不管指定哪个目标平台. /bigobj 可将该地址容量增加至 4,294,967,296 ...
- 清北合肥day2-day5
day2:215这一天的题目相对比较模板化t1:50看错了数据范围求n个点到给出的点哈夫曼距离的最小值我想到的是一种非常zz的做法我们二分答案,然后判断是否在这个距离内有点但是这样前缀和不是很好维护于 ...
- 禁止root直接登陆linux系统
直接修改文件 # vim /etc/ssh/sshd_config SyslogFacility AUTHPRIV PermitRootLogin no RSAAuthentication yes P ...
- 伪分布式hbase2.6.5和hbase1.1.2的配置
1.注意hadoop和hbase的版本兼容问题 目前测试用:hadoop 2.6.5 Hbase 1.1.2 2.创建hadoop用户 Sudo useradd –m hadoop –s /bin/ ...