結果
| 問題 |
No.1301 Strange Graph Shortest Path
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-11-19 01:13:37 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 163 ms / 3,000 ms |
| コード長 | 3,891 bytes |
| コンパイル時間 | 12,429 ms |
| コンパイル使用メモリ | 379,384 KB |
| 実行使用メモリ | 41,340 KB |
| 最終ジャッジ日時 | 2024-09-20 05:20:46 |
| 合計ジャッジ時間 | 20,283 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 33 |
コンパイルメッセージ
warning: variable `N` should have a snake case name --> src/main.rs:50:13 | 50 | let N = self.paths.len(); | ^ help: convert the identifier to snake case: `n` | = note: `#[warn(non_snake_case)]` on by default
ソースコード
use std::{cmp::Reverse, collections::BinaryHeap};
const INF: isize = 1isize << 60;
#[derive(Debug, Clone, Copy)]
struct MinCostFlowEdge {
dest: usize,
capacity: isize,
cost: isize,
rev: usize,
}
impl MinCostFlowEdge {
fn new(dest: usize, capacity: isize, cost: isize, rev: usize) -> MinCostFlowEdge {
MinCostFlowEdge { dest, capacity, cost, rev }
}
}
struct MinCostFlow {
paths: Vec<Vec<MinCostFlowEdge>>,
potential: Vec<isize>,
min_cost: Vec<isize>,
prevv: Vec<usize>,
preve: Vec<usize>,
}
/*
最小費用龍。
fの分だけ流すのにかかる最小のコスト
*/
impl MinCostFlow {
fn new(n: usize) -> MinCostFlow {
MinCostFlow {
paths: vec![vec![]; n],
potential: vec![0isize; n],
min_cost: vec![0isize; n],
prevv: vec![0usize; n],
preve: vec![0usize; n],
}
}
fn pusha2b(&mut self, a: usize, b: usize, capacity: isize, cost: isize) {
let connecta = self.paths[a].len();
let connectb = self.paths[b].len();
self.paths[a].push(MinCostFlowEdge::new(b, capacity, cost, connectb));
self.paths[b].push(MinCostFlowEdge::new(a, 0, -cost, connecta));
}
fn mincost_flow(&mut self, s: usize, t: usize, _f: isize) -> isize {
let N = self.paths.len();
let mut ret = 0isize;
let mut que = BinaryHeap::new();
self.potential = vec![0isize; N];
let mut f = _f;
while f > 0 {
self.min_cost = vec![INF; N];
que.push(Reverse((0, s)));
self.min_cost[s] = 0;
while let Some(Reverse((p, v))) = que.pop() {
if self.min_cost[v] < p { continue; }
for i in 0..self.paths[v].len() {
let edge = self.paths[v][i];
let ncost = self.min_cost[v] + edge.cost + self.potential[v] - self.potential[edge.dest];
if edge.capacity > 0 && self.min_cost[edge.dest] > ncost {
self.min_cost[edge.dest] = ncost;
self.prevv[edge.dest] = v;
self.preve[edge.dest] = i;
que.push(Reverse((self.min_cost[edge.dest], edge.dest)));
}
}
}
if self.min_cost[t] == INF {
return -1;
}
for i in 0..N { self.potential[i] += self.min_cost[i]; }
let mut d = f;
let mut temp = t;
while temp != s {
d = d.min(self.paths[self.prevv[temp]][self.preve[temp]].capacity);
temp = self.prevv[temp];
}
f -= d;
ret += d * self.potential[t];
temp = t;
while temp != s {
let edge = self.paths[self.prevv[temp]][self.preve[temp]];
self.paths[self.prevv[temp]][self.preve[temp]].capacity -= d;
self.paths[temp][edge.rev].capacity += d;
temp = self.prevv[temp];
}
}
ret
}
}
fn main() {
let mut nm = String::new();
std::io::stdin().read_line(&mut nm).ok();
let nm: Vec<usize> = nm.trim().split_whitespace().map(|s| s.parse().unwrap()).collect();
let n = nm[0];
let m = nm[1];
let mut flow = MinCostFlow::new(n);
for _ in 0..m {
let mut uvcd = String::new();
std::io::stdin().read_line(&mut uvcd).ok();
let uvcd: Vec<usize> = uvcd.trim().split_whitespace().map(|s| s.parse().unwrap()).collect();
let u = uvcd[0]-1;
let v = uvcd[1]-1;
let c = uvcd[2] as isize;
let d = uvcd[3] as isize;
flow.pusha2b(u, v, 1, c);
flow.pusha2b(v, u, 1, c);
flow.pusha2b(u, v, 1, d);
flow.pusha2b(v, u, 1, d);
}
println!("{}", flow.mincost_flow(0, n-1, 2));
}