noip 2018 d2t1 旅行
noip 2018 d2t1 旅行
(题目来自洛谷)
给定n个城市,m条双向道路的图, 不存在两条连接同一对城市的道路,也不存在一条连接一个城市和它本身的道路。并且, 从任意一个城市出发,通过这些道路都可以到达任意一个其他城市。小 Y 只能通过这些道路从一个城市前往另一个城市。
小 Y 的旅行方案是这样的:任意选定一个城市作为起点,然后从起点开始,每次可 以选择一条与当前城市相连的道路,走向一个没有去过的城市,或者沿着第一次访问该 城市时经过的道路后退到上一个城市。当小 Y 回到起点时,她可以选择结束这次旅行或 继续旅行。需要注意的是,小 Y 要求在旅行方案中,每个城市都被访问到。(注意:同一条道路不能走两遍,也就是回头路只能走一次)
为了让自己的旅行更有意义,小 Y 决定在每到达一个新的城市(包括起点)时,将 它的编号记录下来。她知道这样会形成一个长度为 nn 的序列。她希望这个序列的字典序 最小,你能帮帮她吗? 对于两个长度均为 n 的序列 A和 B,当且仅当存在一个正整数 x,满足以下条件时, 我们说序列 A 的字典序小于 B。
对于任意正整数 1≤i<x,序列A的第 i 个元素 Ai 和序列 B 的第 i 个元素 Bi 相同。
序列 A 的第 x 个元素的值小于序列 B 的第 x 个元素的值。
输入格式:
输入文件共 m + 1 行。第一行包含两个整数 n,m(m ≤ n),中间用一个空格分隔。
接下来 m 行,每行包含两个整数 u,v (1 ≤ u,v ≤ n),表示编号为 u 和 v 的城市之 间有一条道路,两个整数之间用一个空格分隔。
输出格式:
输出文件包含一行,n 个整数,表示字典序最小的序列。相邻两个整数之间用一个空格分隔。
输入输出样例:
输入样例#1:
6 5
1 3
2 3
2 5
3 4
4 6
输出样例#1:
1 3 2 5 4 6
输入样例#2:
6 6
1 3
2 3
2 5
3 4
4 5
4 6
输出样例#2:
1 3 2 4 5 6
说明
【数据规模与约定】

题解:
首先考虑m==n-1的情况,这种情况下,我们只需要先贪心的经过每个点所连向的点中最小的点,即可得到答案,直接用vector存图,对点进行排序,在树上dfs一遍即可解决,即可得到60分
考虑满分做法,因为n==m则图中有且只有一个环,可以想到这个环上肯定有一条边是不被需要的,因为我们只需要走一遍即可。
我们先找到环,枚举这个环上的每一条边删去,搜索更新答案的最小值,最后输出最小值即可,时间复杂度n^2
不找环直接暴力删边也可过
找环可以拓扑排序,可以并查集,这里采用一种其他的方法
#include<bits/stdc++.h>
#define maxn 5050
using namespace std;
struct node {
int v, w;
node(int vv) {
v = vv;
}
};
vector<node> G[maxn], g[maxn];
void adde(int a, int b) {
G[a].push_back(node(b));
G[b].push_back(node(a));
}
inline int getnum() {
int ans = 0; char c; int flag = 1;
while (!isdigit(c = getchar()) && c != '-');
if (c == '-') flag = -1; else ans = c - '0';
while (isdigit(c = getchar())) ans = ans * 10 + c - '0';
return ans * flag;
}
int n, m;
int vis[maxn];
int cnt = 0;
int ans[maxn], tmp[maxn];
int del[maxn][maxn];
int cmp(node a, node b) {
return a.v < b.v;
}
void dfs(int u, int f) {//假如n == m - 1,则直接贪心选取较小的边,对连向的点进行排序直接遍历图即可
ans[++cnt] = u;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if (v != f)
dfs(v, u);
}
}
int num;
int find(int u, int f) {//找环
if (num) return 0;//假如已经找到了环的起点,则退出搜索,因为此时环已经构建好了
vis[u] = 1;//已经遍历过这个点
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if (v == f) continue;
if (vis[v]) {//假如找到了遍历过的点,说明形成了环
num = v;//环的起点为num
g[u].push_back(node(v));//将构成环的这条边加入
return 1;//返回1,代表可以找到环
}
if (find(v, u)) {//假如从v开始能找到环的话
if (v == num) return 0;//如果连向的点就是起点,则返回,因为这条边不在环内
g[u].push_back(node(v));//将在环内的边加入图g
return 1;//返回可以找到环,这样就可以将一整个环内的边全部加入g
}
}
}
void dfs1(int u) {
if (vis[u]) return;
vis[u] = 1;
tmp[++cnt] = u;
for (int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
if (del[u][v] == 0) dfs1(v);
}
}
int check() {
for (int i = 1; i <= n; i++) {
if (ans[i] == tmp[i]) continue;
if (ans[i] > tmp[i]) return 1;
else return 0;
}
}
int main() {
n = getnum(), m = getnum();
for (int i = 1; i <= m; i++) {
int a = getnum(), b = getnum();
adde(a, b);
}
for (int i = 1; i <= n; i++) {
sort(G[i].begin(), G[i].end(), cmp);//排序
}
for (int i = 1; i <= n; i++) {
ans[i] = n;//将ans赋值为最大值
}
if (n == m) {
find(1, -1);
for (int i = 1; i <= n; i++) {
for (int j = 0; j < g[i].size(); j++) {
memset(vis, 0, sizeof(vis));
int v = g[i][j].v;
del[i][v] = 1; del[v][i] = 1;//删边
cnt = 0;
dfs1(1);
del[i][v] = 0; del[v][i] = 0;//恢复
if (check()) {
for (int i = 1; i <= n; i++) {
ans[i] = tmp[i];
}
}
}
}
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
return 0;
}
dfs(1, -1);
for (int i = 1; i <= cnt; i++) {
cout << ans[i] << " ";
}
return 0;
}
noip 2018 d2t1 旅行的更多相关文章
- NOIp 2018 D2T1 旅行//未完成
这个题没有认真读的话就会写下以下的DD代码 #include<bits/stdc++.h> #define N 5010 using namespace std; int n,m; int ...
- [OI]Noip 2018总结(普及)
考砸了,还有原谅我代码十分有限的可读性. 一个人的真正伟大之处就在于他能够认识到自己的渺小.——保罗 从一年前初一九月到现在18年10月接触OI已经有一年了.几次模拟赛也自我感觉良好,都过了一等的线, ...
- noip 2018 D1T3 赛道修建
noip 2018 D1T3 赛道修建 首先考虑二分答案,这时需要的就是对于一个长度求出能在树中选出来的最多的路径条数.考虑到一条路径是由一条向上的路径与一条向下的路径构成,或者仅仅是向上或向下的路径 ...
- [NOIP2018 TG D2T1]旅行
题目大意:$NOIP\;TG\;D2T1$ 题解:一棵树的很简单,第一个点一定是$1$,只需要对每个节点,找最小的没有访问过的节点访问即可,我写的是$O(n\log_2n)$. 考虑基环树的部分,一个 ...
- NOIP 2018 总结
NOIP 2018 总结 提高组: 应得分 \(100 + 100 + 40 + 100 + 50 + 44 = 434\). 考后期望得分 \(100 + 100 + 20 + 100 + 50 + ...
- NOIP 2018 真・退役记
目录 NOIp 2018 真・退役记 7.01 7.05 \(summary\) 7.12 7.18 7.26 - 7.27 8.2 8.3 8.3 8.7 8.9 8.20 8.24 8.27 8. ...
- NOIP 2018 普及组 解题报告
目录 标题统计 题目链接 思路 代码 龙虎斗 题目链接: 思路 代码 摆渡车 题目链接: 思路 对称二叉树 题目链接 思路: 先来解释一下为毛现在才来发解题报告: 其实博主是参加过NOIP 2018普 ...
- NOIP 2018旅行题解
从佳木斯回来刷一刷去年没A的题 题目描述 小 Y 是一个爱好旅行的 OIer.她来到 X 国,打算将各个城市都玩一遍. 小Y了解到, X国的 nn 个城市之间有 mm 条双向道路.每条双向道路连接两个 ...
- noip 2018 Day2 T1 旅行
暴力删边,暴力枚举 #include <bits/stdc++.h> using namespace std; #define MAXM 5010 inline int read() { ...
随机推荐
- win10安装mac系统
https://baijiahao.baidu.com/s?id=1587241720383991895&wfr=spider&for=pc https://mp.weixin.qq. ...
- Liunx开发(Extjs4.1+desktop+SSH2超强视频教程实践)(2)
然后装eclipse: 为啥默认是搜狗导航: java还没装呢: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downlo ...
- 一、Web 如何工作的
平常我们在浏览器中输入一个网址,随即看到一个页面,这个过程是怎样实现的呢?下面用一幅图来说明: 整个流程如下: 1.域名解析 浏览器会解析域名对应的IP地址 PS:DNS服务器的知识 2.建立TCP ...
- Go - 环境安装
目录 你好,Go语言 环境安装 目录结构 命令 开发工具 学习网址 小结 你好,Go语言 Go 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. 因工作需要,准备入坑,先从环境安装开始 ...
- 2018.2.7 css 的一些方法盒子模型
css 的一些方法 1.盒模型代码简写 盒模型的外边距(margin).内边距(padding)和边框(border)设置上下左右四个方向的边距是按照顺时针方向设置的:上右下左.具体应用在margin ...
- Rhadoop安装
1.ubuntu,hadoop,R,jdk安装好 2.下载Rhadoop项目的的三个包,rmr,hdfs,rHBase存放到Downloads/R. 3.切换到root 4.安装依赖的库 ~R CMD ...
- jenkins重置build序号
来源:https://www.jianshu.com/p/e342b52d45e1 执行命令:item = Jenkins.instance.getItemByFullName("your- ...
- redhat linux6.5升级openssh
1.下载最新的openssh包 http://www.openssh.com/portable.html#http 2.升级openssh之前要先打开服务器telnet,通过telnet登录服务器,因 ...
- (80)zabbix性能优化中的几个建议
随着zabbix的广泛应用,少数人的zabbix服务器在性能上出现瓶颈,或者在未来会出现性能方面的瓶颈,接下来讨论几个有效并且简单的优化方案. 服务器硬件 想通过几个简单的配置让服务器提高成倍的性能, ...
- HTTP 配置与编译安装
目录 HTTP 配置与编译安装 HTTP 相关配置 DSO 定义'Main' Server 的文档页面路径 定义站点主页面 站点访问控制常见机制 基于源地址实现访问控制 日志设定 设定默认字符集 定义 ...