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. 修改在一些图 ...
随机推荐
- Caused by: java.lang.ClassNotFoundException: Class org.openx.data.jsonserde.JsonSerDe not found
Caused by: java.lang.ClassNotFoundException: Class org.openx.data.jsonserde.JsonSerDe not found 解决方法 ...
- pyinstall打包工具使用简介
使用pyinstall进行多个文件打包,直接打包主入口文件即可 pyinstaller MainUI.py -F -n ServerMonitorv200 -i PIC.ico -w 此处MainUI ...
- swiper.js Bscroll 轮播
<!-- 轮播banner图 --> <div class="banner"> <div class="swiper-container&q ...
- kafka rebalance你真的了解吗
介绍 今天主要分享一下 kafka 的 rebalance,在 kafka 中,rebalance 是一个十分重要的概念,很多时候引发的一些问题可能都是由于 rebalance 引起的,rebalan ...
- VUE-生命周期/请求数据
使用方法 --- 4个before,4个ed,创造,装载,更新,销毁 初始化阶段 beforeCreate(){} // 准备怀孕 created(){} // 怀上了 *************** ...
- Centos7安装配置MySQL 5.6
Centos7安装配置MySql 5.6 首先下载MySql5.6的安装包,具体安装方式分为yum安装与离线安装.在新版本的CentOS7中,默认的数据库已更新为了Mariadb,而非 MySQL. ...
- R语言包和中文乱码解决方案
常用R语言包 --数据处理:lubridata ,plyr ,reshape2,stringr,formatR,mcmc: --机器学习:nnet,rpart,tree,party,lars,boos ...
- kubernetes 启用 PHP + Nginx 网页环境
kubernetes 启用 PHP + Nginx 网页环境 传统安装方式进行安装步骤较多,使用kubernetes可以实现快速启用环境,在测试或者线上都可以做到快速 启用 编写 yaml 文件 [r ...
- sqlite3使用2
一. 在cmd中打开SQLite 1.进入数据库 通过输入 d:cd D:\--\SQLitesqlite3 进入数据库 查看数据库的基本信息: .help 显示各种重要的SQLite点命令的列表.s ...
- python入门教程之十三错误和异常
作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍. Python 有两种错误很容易辨认:语法错误和异常. Python as ...