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. 修改在一些图 ...
随机推荐
- ps18.3.20
PS添加图层蒙版,然后画笔,括号是画笔的大小,,还要调,不透明度
- UAC的详细讲解(转载)
win32中也有对UAC的操作方法 网址:https://blog.csdn.net/zuishikonghuan/article/details/46965159?locationNum=7& ...
- 例题1:shell脚本
题目总结: 1.搜索子域名的shell脚本 2.嗅探并抓去网页快照shell脚本 3.漏洞利用程序下载脚本 题目一:依次输入以下代码即可: 1.wget www.megacorpone.com 2. ...
- 基于LAMP搭建WordPress博客
1.安装Apache. 1)执行如下命令,安装Apache服务及其扩展包. yum -y install httpd mod_ssl mod_perl mod_auth_mysql 2)执行如下命令, ...
- MS SQL Server 删除重复行数据
您可以使用以下 SQL 语句删除 MS SQL Server 表中重复的行: WITH CTE AS ( SELECT ROW_NUMBER() OVER(PARTITION BY column1, ...
- Python Web开发初试,基于Flask
目录 关于web框架 Python flask使用 关于web框架 仅仅对于应用层的coder而言,web框架的使用其实就是写路由,分发路由,写输出.当然如果要安全,要测试,要写优秀的接口,那需要继续 ...
- Linux Redhat ens33不显示IP问题
[第一步]:查看系统网卡设备 : ip addr show
- 简单入门echart方法
图表用echart, 然后前端的 HTML 跟 nodejs , nodejs 去调用 后端PHP的接口 链接:https://www.jianshu.com/p/1f2c37c5c02f 官网:h ...
- ACM-NEFU-2020大一寒假培训三(暴力)
A.二倍的问题 Description 给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍.比如给定1 4 3 2 9 7 18 22,得到的答案是3, ...
- TSDB - VictoriaMetrics 技术原理浅析
版权说明: 本文章版权归本人及博客园共同所有,转载请在文章前标明原文出处( https://www.cnblogs.com/mikevictor07/p/17258452.html ),以下内容为个人 ...