complete 2056.rs 16724.rs 17143.rs 25186.rs 26545.rs 27172.rs 30524.rs
This commit is contained in:
169
storage/zeta/rs/completed/2056.rs
Normal file
169
storage/zeta/rs/completed/2056.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
use std::io::stdin;
|
||||
|
||||
mod update_heap {
|
||||
use std::cmp::Ordering;
|
||||
|
||||
pub struct Task {
|
||||
pub idx: usize,
|
||||
pub remaining_time: usize,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub fn new(idx: usize, time: usize) -> Self {
|
||||
Self {
|
||||
idx,
|
||||
remaining_time: time,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<Self> for Task {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.remaining_time == other.remaining_time
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd<Self> for Task {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.remaining_time.partial_cmp(&other.remaining_time)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UpdateHeap {
|
||||
data: Vec<Task>,
|
||||
}
|
||||
|
||||
impl UpdateHeap {
|
||||
pub fn new() -> Self {
|
||||
Self { data: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.data.is_empty()
|
||||
}
|
||||
|
||||
pub fn push(&mut self, item: Task) {
|
||||
self.data.push(item);
|
||||
let idx = self.data.len() - 1;
|
||||
self.sift_up(idx);
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<Task> {
|
||||
if self.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let last_idx = self.data.len() - 1;
|
||||
self.data.swap(0, last_idx);
|
||||
let ret = self.data.pop().unwrap();
|
||||
if !self.data.is_empty() {
|
||||
self.sift_down(0);
|
||||
}
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
fn sift_up(&mut self, mut idx: usize) {
|
||||
while idx > 0 {
|
||||
let parent = (idx - 1) / 2;
|
||||
if self.data[parent] > self.data[idx] {
|
||||
self.data.swap(parent, idx);
|
||||
idx = parent;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sift_down(&mut self, mut idx: usize) {
|
||||
while idx < self.data.len() / 2 {
|
||||
let left = 2 * idx + 1;
|
||||
let right = 2 * idx + 2;
|
||||
let mut child = left;
|
||||
if right < self.data.len() && self.data[right] < self.data[left] {
|
||||
child = right;
|
||||
}
|
||||
if self.data[child] < self.data[idx] {
|
||||
self.data.swap(child, idx);
|
||||
idx = child;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, dt: usize) {
|
||||
self.data.iter_mut().for_each(|x| x.remaining_time -= dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use crate::update_heap::Task;
|
||||
use update_heap::UpdateHeap;
|
||||
|
||||
fn get_inv_dependencies_edges(tasks: &Vec<(usize, Vec<usize>)>) -> Vec<Vec<usize>> {
|
||||
let mut inv_dependencies = vec![vec![]; tasks.len()];
|
||||
for i in 0..tasks.len() {
|
||||
for &v in tasks[i].1.iter() {
|
||||
inv_dependencies[v].push(i);
|
||||
}
|
||||
}
|
||||
inv_dependencies
|
||||
}
|
||||
|
||||
fn get_minimum_cost_of_tasks(tasks: &Vec<(usize, Vec<usize>)>) -> usize {
|
||||
let inv_dependencies = get_inv_dependencies_edges(tasks);
|
||||
|
||||
let mut indeg: Vec<usize> = vec![0; tasks.len()];
|
||||
for v in inv_dependencies.iter() {
|
||||
for &w in v.iter() {
|
||||
indeg[w] += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mut heap: UpdateHeap = UpdateHeap::new();
|
||||
|
||||
for (i, deg) in indeg.iter().enumerate() {
|
||||
if *deg == 0 {
|
||||
heap.push(Task::new(i, tasks[i].0));
|
||||
}
|
||||
}
|
||||
|
||||
let mut total_time = 0;
|
||||
|
||||
while !heap.is_empty() {
|
||||
let task = heap.pop().unwrap();
|
||||
|
||||
total_time += task.remaining_time;
|
||||
heap.update(task.remaining_time);
|
||||
inv_dependencies[task.idx].iter().for_each(|&v| {
|
||||
indeg[v] -= 1;
|
||||
if indeg[v] == 0 {
|
||||
heap.push(Task::new(v, tasks[v].0));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
total_time
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut line = String::new();
|
||||
stdin().read_line(&mut line).unwrap();
|
||||
let n = line.trim_end().parse::<usize>().unwrap();
|
||||
line.clear();
|
||||
let tasks = (0..n)
|
||||
.map(|_| {
|
||||
stdin().read_line(&mut line).unwrap();
|
||||
let mut iter = line.split_whitespace();
|
||||
let cost = iter.next().unwrap().parse::<usize>().unwrap();
|
||||
let _ = iter.next();
|
||||
let depends = iter
|
||||
.map(|x| x.parse::<usize>().unwrap() - 1)
|
||||
.collect::<Vec<usize>>();
|
||||
line.clear();
|
||||
(cost, depends)
|
||||
})
|
||||
.collect::<Vec<(usize, Vec<usize>)>>();
|
||||
|
||||
println!("{}", get_minimum_cost_of_tasks(&tasks));
|
||||
}
|
||||
Reference in New Issue
Block a user