2023-02-14:魔物了占领若干据点,这些据点被若干条道路相连接, roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。 现在勇者要将按照以下原则将这些据点逐一夺回:
2023-02-14:魔物了占领若干据点,这些据点被若干条道路相连接,
roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。
现在勇者要将按照以下原则将这些据点逐一夺回:
在开始的时候,勇者可以花费资源先夺回一些据点,
初始夺回第 j 个据点所需消耗的资源数量为 cost[j]
接下来,勇者在不消耗资源情况下,
每次可以夺回一个和「已夺回据点」相连接的魔物据点,
并对其进行夺回。
为了防止魔物暴动,勇者在每一次夺回据点后(包括花费资源夺回据点后),
需要保证剩余的所有魔物据点之间是相连通的(不经过「已夺回据点」)。
请返回勇者夺回所有据点需要消耗的最少资源数量。
输入保证初始所有据点都是连通的,且不存在重边和自环。
输入:cost = [1,2,3,4,5,6],roads = [[0,1],[0,2],[1,3],[2,3],[1,2],[2,4],[2,5]]。
输出:6。
答案2023-02-24:
代码用rust编写。代码如下:
执行结果如下:
use std::iter::repeat;
fn main() {
let cost = vec![1, 2, 3, 4, 5, 6];
let roads = vec![
vec![0, 1],
vec![0, 2],
vec![1, 3],
vec![2, 3],
vec![1, 2],
vec![2, 4],
vec![2, 5],
];
let ans = unsafe { Solution::minimum_cost(cost, roads) };
println!("ans = {:?}", ans);
}
struct Solution {}
impl Solution {
pub fn minimum_cost(cost: Vec<i32>, roads: Vec<Vec<i32>>) -> i64 {
let mut roads = roads;
let n = cost.len() as i32;
if n == 1 {
return cost[0] as i64;
}
let m = roads.len() as i32;
let mut dc = DoubleConnectedComponents::new(n, m, &mut roads);
let mut ans: i64 = 0;
// dcc {a,b,c} {c,d,e}
if dc.dcc.len() == 1 {
ans = i64::MAX;
for num in cost.iter() {
ans = get_min(ans, *num as i64);
}
} else {
// 不只一个点双连通分量
let mut arr: Vec<i32> = vec![];
for set in dc.dcc.iter() {
let mut cutCnt = 0;
let mut curCost = i32::MAX;
for nodes in set.iter() {
if dc.cut[*nodes as usize] {
cutCnt += 1;
} else {
curCost = get_min(curCost, cost[*nodes as usize]);
}
}
if cutCnt == 1 {
arr.push(curCost);
}
}
arr.sort_by(|a, b| a.partial_cmp(b).unwrap());
for i in 0..arr.len() as i32 - 1 {
ans += arr[i as usize] as i64;
}
}
return ans;
}
}
fn get_min<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a < b {
a
} else {
b
}
}
struct DoubleConnectedComponents {
// 链式前向星建图
head: Vec<i32>,
next: Vec<i32>,
to: Vec<i32>,
dfn: Vec<i32>,
low: Vec<i32>,
stack: Vec<i32>,
dcc: Vec<Vec<i32>>,
cut: Vec<bool>,
edgeCnt: i32,
dfnCnt: i32,
top: i32,
root: i32,
}
impl DoubleConnectedComponents {
pub fn new(n: i32, m: i32, roads: &mut Vec<Vec<i32>>) -> Self {
let mut ans = DoubleConnectedComponents {
head: vec![],
next: vec![],
to: vec![],
dfn: vec![],
low: vec![],
stack: vec![],
dcc: vec![],
cut: vec![],
edgeCnt: 0,
dfnCnt: 0,
top: 0,
root: 0,
};
ans.init(n, m);
ans.createGraph(roads);
ans.creatDcc(n);
ans
}
fn init(&mut self, n: i32, m: i32) {
let t = repeat(-1).take(n as usize).collect::<Vec<i32>>();
self.head = t;
let t = repeat(0).take((m << 1) as usize).collect::<Vec<i32>>();
self.next = t;
let t = repeat(0).take((m << 1) as usize).collect::<Vec<i32>>();
self.to = t;
let t = repeat(0).take(n as usize).collect::<Vec<i32>>();
self.dfn = t;
let t = repeat(0).take(n as usize).collect::<Vec<i32>>();
self.low = t;
let t = repeat(0).take(n as usize).collect::<Vec<i32>>();
self.stack = t;
let t = repeat(false).take(n as usize).collect::<Vec<bool>>();
self.cut = t;
self.edgeCnt = 0;
self.dfnCnt = 0;
self.top = 0;
self.root = 0;
}
fn createGraph(&mut self, roads: &mut Vec<Vec<i32>>) {
for edges in roads.iter() {
self.add(edges[0], edges[1]);
self.add(edges[1], edges[0]);
}
}
fn add(&mut self, u: i32, v: i32) {
self.to[self.edgeCnt as usize] = v;
self.next[self.edgeCnt as usize] = self.head[u as usize];
self.head[u as usize] = self.edgeCnt;
self.edgeCnt += 1;
}
fn creatDcc(&mut self, n: i32) {
for i in 0..n {
// 0 1 2 3 n-1
if self.dfn[i as usize] == 0 {
self.root = i;
self.tarjan(i);
}
}
}
fn tarjan(&mut self, x: i32) {
self.dfnCnt += 1;
self.low[x as usize] = self.dfnCnt;
self.dfn[x as usize] = self.low[x as usize];
self.stack[self.top as usize] = x;
self.top += 1;
let mut flag = 0;
if x == self.root && self.head[x as usize] == -1 {
self.dcc.push(vec![]);
let t = (self.dcc.len() as i32 - 1) as usize;
self.dcc[t].push(x);
} else {
// 当前来到的节点是x
// x {a,b,c}
let mut i = self.head[x as usize];
while i >= 0 {
// y是下级节点
let mut y = self.to[i as usize];
if self.dfn[y as usize] == 0 {
// y点没遍历过!
self.tarjan(y);
if self.low[y as usize] >= self.dfn[x as usize] {
// 正在扎口袋
flag += 1;
if x != self.root || flag > 1 {
self.cut[x as usize] = true;
}
let mut curAns: Vec<i32> = vec![];
// 从栈里一次弹出节点
// 弹到y停!
// 弹出的节点都加入集合,x也加入,x不弹出
self.top -= 1;
let mut z = self.stack[self.top as usize];
while z != y {
curAns.push(z);
self.top -= 1;
z = self.stack[self.top as usize];
}
curAns.push(y);
curAns.push(x);
self.dcc.push(curAns);
}
self.low[x as usize] = get_min(self.low[x as usize], self.low[y as usize]);
} else {
// y点已经遍历过了!
self.low[x as usize] = get_min(self.low[x as usize], self.dfn[y as usize]);
}
i = self.next[i as usize];
}
}
}
}

2023-02-14:魔物了占领若干据点,这些据点被若干条道路相连接, roads[i] = [x, y] 表示编号 x、y 的两个据点通过一条道路连接。 现在勇者要将按照以下原则将这些据点逐一夺回:的更多相关文章
- LinkedIn的即时消息:在一台机器上支持几十万条长连接
最近我们介绍了LinkedIn的即时通信,最后提到了分型指标和读回复.为了实现这些功能,我们需要有办法通过长连接来把数据从服务器端推送到手机或网页客户端,而不是许多当代应用所采取的标准的请求-响应模式 ...
- Sql语句中两个比较迷糊的概念:“连接查询” 与 “外键约束”
Sql语句中两个比较迷糊的概念:“连接查询” 与 “外键约束 Sql 中的连接查询:就是为了避免笛卡尔积,因为涉及到多表查询的化,不使用连接查询,会先将多个互相乘,求出笛卡尔积,然后在在里面查询符合的 ...
- 计算机网络:TCP协议建立连接的过程为什么是三次握手而不是两次?【对于网上的两种说法我的思考】
网上关于这个问题吵得很凶,但是仔细看过之后我更偏向认为两种说的是一样的. 首先我们来看看 TCP 协议的三次握手过程 如上图所示: 解释一下里面的英文: 里面起到作用的一些标志位就是TCP报文首部里的 ...
- TCP 两次握手为什么无法阻止历史连接?
摘要:在两次握手的情况下,「被动发起方」没有中间状态给「主动发起方」来阻止历史连接,导致「被动发起方」可能建立一个历史连接,造成资源浪费. 本文分享自华为云社区<TCP 两次握手为什么无法阻止历 ...
- 2019.02.14 codechef Chef at the Food Fair(线段树+泰勒展开)
传送门 题意:现在有nnn个位置,每个位置上有一个值aia_iai. 要求支持如下两种操作: 区间乘vvv 求区间的(1−ai)(1-a_i)(1−ai)之积 思路: 考虑转换式子: Ans=∏i ...
- 2016.02.14 总结JS事件
今天主要总结JS事件的基本知识以及使用技巧,并作出相应的DEMO.
- Html5 reset表 2015年1月7日15:02:14
/* HTML5 Reset :: style.css ---------------------------------------------------------- We have learn ...
- NO.009-2018.02.14《临江仙·送钱穆父》宋代:苏轼
临江仙·送钱穆父_古诗文网 临江仙·送钱穆父 宋代:苏轼 一别都门三改火,天涯踏尽红尘.依然一笑作春温.无波真古井,有节是秋筠.自从我们在京城分别一晃又三年,远涉天涯你奔走辗转在人间.相逢一笑时依然像 ...
- 梦想Android版CAD控件(安卓CAD二次开发,安卓CAD控件)2023.02.26更新
下载地址:https://www.mxdraw.com/ndetail_40240.html1. 增加willBeReturnStart事件2. 增加使用OpenGL缓存3. 优化界面响应时间4. 修 ...
- MxDraw云图平台(H5在线CAD) 网页CAD,网页查看CAD图纸,2023.02.26更新
下载地址:https://www.mxdraw.com/ndetail_40241.html1. 梦想服务上传CAD文件格式转换,增加转换后的文件例表返回2. 增加绘制图片Tag功能3. 修改在一些图 ...
随机推荐
- jmeter之阶段式压测
一.bzm - Concurrency Thread Group 1.什么是阶梯式压测 阶梯式压测,就是对系统的压力呈现阶梯性增加的过程,每个阶段压力值都要增加一个数量值,最终达到一个预期值.然后保持 ...
- arcengine标注转注记
只是将在arcmap中添加注记的方式模拟了一遍,因此,首先显示标注(Label),而后将其转换为注记(Annotation)(Convert Label To Annotation) /******* ...
- python之自动化连连看脚本-第一关不动-小记
(如想转载,请联系博主或贴上本博地址) 仅供学习python之用,勿用做商业用途.运行环境为1920*1080屏幕,python3.7,win7,谷歌浏览器版本 75.0.3770.100. 参考ht ...
- Hugging Face 每周速递: Chatbot Hackathon;FLAN-T5 XL 微调;构建更安全的 LLM
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...
- Nacos与OpenFeign开发
目录 1.前言 2.生产者 3.消费者 4.扩展 1.前言 我的话是微服务B调用微服务A的controller层 2.生产者 微服务A请求接口如下: @GetMapping("/listUn ...
- 给我一块画布,我可以造一个全新的跨端UI
一.源起 作者是名超大龄程序员,曾涉及了包括Web端.桌面端.移动端等各类前端技术,深受这些前端技术的苦,主要但不限于: 每种技术编写代码的语言及技术完全不同,同样呈现形式的组件各端无法通用: 大 ...
- java注解与反射--3
java注解与反射--3 类的加载与ClassLoader java内存 堆 存放new的对象和数组 可以被所有的线程共享,不会存放别的对象引用 栈 存放基本变量类型 引用对象的变量 方法区 可以被所 ...
- java多线程--6 死锁问题 锁Lock
java多线程--6 死锁问题 锁Lock 死锁问题 多个线程互相抱着对方需要的资源,然后形成僵持 死锁状态 package com.ssl.demo05; public class DeadLock ...
- 1 - Windows 10 - Python 类的常用高级系统函数(方法)通识
@ 目录 一.系统函数__init__() 初始化类函数 二.系统函数__call__() 调用对象函数 三.系统函数__dict__类属性查询函数 四.系统函数__str__()描述类信息函数 五. ...
- JVM内存结构与内存模型
这篇文章重点讲一下jvm的内存结构和内存模型的知识点.(2023.3.11) 1.内存结构 jvm内存区域主要分为线程私有区域[程序计数器,虚拟机栈,本地方法栈],线程共享区域[堆,方法区],直接内存 ...