题目链接

题目

题目描述

lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。

游戏进行到最后,lxhgww遇到了终极boss,这个终极boss很奇怪,攻击他的装备所使用的属性值必须从1开始连续递增地攻击,才能对boss产生伤害。也就是说一开始的时候,lxhgww只能使用某个属性值为1的装备攻击boss,然后只能使用某个属性值为2的装备攻击boss,然后只能使用某个属性值为3的装备攻击boss……以此类推。现在lxhgww想知道他最多能连续攻击boss多少次?

输入描述

输入的第一行是一个整数N,表示lxhgww拥有N种装备

接下来N行,是对这N种装备的描述,每行2个数字,表示第i种装备的2个属性值

输出描述

输出一行,包括1个数字,表示lxhgww最多能连续攻击的次数。

示例1

输入

3
1 2
3 2
4 5

输出

2

备注

对于 \(30\%\) 的数据,保证 \(N \leq 1000\)

对于 \(100\%\) 的数据,保证 \(N \leq 1000000\)

题解

方法一

知识点:图论,DFS。

把装备的两个属性值抽象成一条边的两个点,每条边只能选择一个点,那么对于一个连通图有大于等于点数量的边,那么这个连通图是存在环的,那就一定有方法使得所有点都选到,否则最大值不能选到。

于是,建图后枚举所有点的连通情况,如果存在环就是所有都能取到,如果不存在环则最大值取不到,将第一个不能取到的值设为最大值,如此遍历所有数字即可得到确定的第一个不能取到的数字,答案就是这个数字减一。

时间复杂度 \(O(n)\)

空间复杂度 \(O(n)\)

方法二

知识点:并查集。

原理和方法一一样,将存在关系的点放入一个集合,根节点权值设为这个集合的最大值,如果存在两个点在一个集合后又被合并一次说明这个集合的点存在环,否则没有。

遍历所有集合找到不能取到最大值的集合中的最小值,减一即是答案。

时间复杂度 \(O(n)\)

空间复杂度 \(O(1)\)

方法三

知识点:贪心。

对于每个装备取较小属性值,如果这个值已经取过了那就取较大的属性值,将访问信息存入一个数组,如此得到一个最小能取到的属性值的数组,遍历数组直到第一个不能去到的数为止,减一即是答案。

时间复杂度 \(O(n)\)

空间复杂度 \(O(1)\)

代码

方法一

#include <bits/stdc++.h>

using namespace std;

vector<int> g[10007];
bool vis[10007];
int maxn;
bool dfs(int u, int fa) {
bool flag = false;///判断环
for (int i = 0;i < g[u].size();i++) {
int v = g[u][i];
if (fa == v) continue; ///和其他标记不一样,父节点单独考虑
if (vis[v]) { flag = true; continue; }///有环还不能跳出,要找到最大值
vis[v] = 1;///标记
maxn = max(maxn, v);///更新连通块最大值
if (dfs(v, u)) flag = true;///传递环信息
}
return flag;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
int ans = 0;
for (int i = 0;i < n;i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
ans = max({ ans,u,v });
}
ans++;///表示不能到达的第一个数
for (int i = 1;i <= ans - 1;i++) {
if (!vis[i]) {
vis[i] = 1;
maxn = i;
if (!dfs(i, 0)) ans = min(ans, maxn);
}
///如果没访问,且所在连通块无环,则仅最大数一定不可达,更新为ans
///其他数如果之前的数都可达,则一定可达,因此访问过的不需要再次访问
}
cout << ans - 1 << '\n';///遍历区间后能确定ans
return 0;
}

方法二

#include <bits/stdc++.h>

using namespace std;

int fa[10007];
int maxn[10007];///维护连通块最大值
bool flag[10007];///维护环信息 int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
} void merge(int u, int v) {
int ru = find(u);
int rv = find(v);
if (ru == rv) flag[ru] = 1;
else {
fa[ru] = rv;
maxn[rv] = max(maxn[ru], maxn[rv]);
flag[rv] |= flag[ru];
}
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
for (int i = 1;i <= 10000;i++) fa[i] = i, maxn[i] = i;
int n;
cin >> n;
int ans = 0;
for (int i = 0;i < n;i++) {
int u, v;
cin >> u >> v;
merge(u, v);
ans = max({ ans,u,v });
}
ans++;
for (int i = 1;i <= ans - 1;i++) {
if (fa[i] == i && !flag[i]) ans = min(ans, maxn[i]);
}
cout << ans - 1 << '\n';
return 0;
}

方法三

#include <bits/stdc++.h>

using namespace std;

bool vis[10007];

int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n;
cin >> n;
for (int i = 0;i < n;i++) {
int u, v;
cin >> u >> v;
if (!vis[min(u, v)]) vis[min(u, v)] = 1;
else vis[max(u, v)] = 1;
}
int ans = 1;
while (vis[ans]) {
ans++;
}
cout << ans - 1 << '\n';
return 0;
}

NC20566 [SCOI2010]游戏的更多相关文章

  1. BZOJ 1854: [Scoi2010]游戏 无向图判环

    题目链接: 题目 1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MB 问题描述 lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装 ...

  2. BZOJ 1854: [Scoi2010]游戏( 二分图最大匹配 )

    匈牙利算法..从1~10000依次找增广路, 找不到就停止, 输出答案. --------------------------------------------------------------- ...

  3. 1854: [Scoi2010]游戏

    1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 2538  Solved: 905[Submit][Status] ...

  4. 【BZOJ】1854: [Scoi2010]游戏【二分图】

    1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 6759  Solved: 2812[Submit][Status] ...

  5. BZOJ 1854: [Scoi2010]游戏 并查集

    1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 2672  Solved: 958[Submit][Status][ ...

  6. 【BZOJ1854】[Scoi2010]游戏 二分图最大匹配

    [BZOJ1854][Scoi2010]游戏 Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有2个属性,这些属性的值用[1,10000]之间的数表示.当 ...

  7. bzoj1854 [Scoi2010]游戏 ([SCOI2010]连续攻击游戏)

    bzoj1854 [Scoi2010]游戏 ([SCOI2010]连续攻击游戏) 据说正解是并查集???我不会 这不是一道匈♂牙利好题吗??? 一个装备的两个属性都向它连边,然后跑一遍匈♂牙利 注意: ...

  8. 1854: [Scoi2010]游戏[并查集]

    1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 4938  Solved: 1948[Submit][Status] ...

  9. [BZOJ1854][SCOI2010]游戏 二分图最大匹

    1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 5316  Solved: 2128[Submit][Status] ...

随机推荐

  1. Flume 详解&实战

    Flume 1. 概述 Flume是一个高可用,高可靠,分布式的海量日志采集.聚合和传输的系统.Flume基于流式架构,灵活简单. Flume的作用 Flume最主要的作用就是,实时读取服务器本地磁盘 ...

  2. C#/VB.NET 在Excel单元格中应用多种字体格式

    在Excel中,可对单元格中的字符串设置多种不同样式,通常只需要获取到单元格直接设置样式即可,该方法设置的样式会应用于该单元格中的所有字符.如果需要对单元格中某些字符设置样式,则可以参考本文中的方法. ...

  3. Spring按业务模块输出日志到不同的文件

    一.背景 在我们开发的过程中,可能存在如下情况: 1.有些时候我们需要调用第三方的接口,一般情况下,调用接口,我们都会记录请求的入参和响应的.如果我们自己系统的日志和第三方的日志混合到一个日志文件中, ...

  4. 我使用Spring AOP实现了用户操作日志功能

    我使用Spring AOP实现了用户操作日志功能 今天答辩完了,复盘了一下系统,发现还是有一些东西值得拿出来和大家分享一下. 需求分析 系统需要对用户的操作进行记录,方便未来溯源 首先想到的就是在每个 ...

  5. Node.js的多版本管理工具 gnvm(win环境)的详细安装教程(图解步骤、通俗易懂、亲测有效)

    前言 本篇随笔主要写了如何安装并使用node多版本管理工具gnvm(windowns环境下) 作为自己对多版本工具gnvm知识的总结与笔记. 百度云盘gnvm应用程序包 获取链接(个人应用地址如下): ...

  6. JavaScript正则中//g, g 的作用

    //正则表达式的标准写法regexp = new RegExp(pattern[, flag]); pattern:  模板的用法是关键,也是本章的主要内容.    flag:     "i ...

  7. WC2019

    好题啊! 数树 \(\text{opt = 0, 6 pts.}\) 显然答案为 \(y^{n-|E_1∩E_2|}\) . \(\text{opt = 1, 47 pts.}\) \[\sum_{E ...

  8. Redis中的原子操作(2)-redis中使用Lua脚本保证命令原子性

    Redis 如何应对并发访问 使用 Lua 脚本 Redis 中如何使用 Lua 脚本 EVAL EVALSHA SCRIPT 命令 SCRIPT LOAD SCRIPT EXISTS SCRIPT ...

  9. 从零开始实现lmax-Disruptor队列(二)多消费者、消费者组间消费依赖原理解析

    MyDisruptor V2版本介绍 在v1版本的MyDisruptor实现单生产者.单消费者功能后.按照计划,v2版本的MyDisruptor需要支持多消费者和允许设置消费者组间的依赖关系. 由于该 ...

  10. JAVA用for循环打印*三角形

    public class Sanjiaoxing { //本节为for循环的嵌套结构练习 public static void main(String[] args) { // TODO Auto-g ...