結果

問題 No.5007 Steiner Space Travel
ユーザー matsu7874
提出日時 2022-07-30 17:35:13
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 9 ms / 1,000 ms
コード長 7,386 bytes
コンパイル時間 1,131 ms
実行使用メモリ 5,452 KB
スコア 6,026,701
最終ジャッジ日時 2022-07-30 17:35:16
合計ジャッジ時間 3,010 ms
ジャッジサーバーID
(参考情報)
judge14 / judge13
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 30
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: unused import: `std::cmp::Reverse`
 --> Main.rs:1:5
  |
1 | use std::cmp::Reverse;
  |     ^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `std::collections::BinaryHeap`
 --> Main.rs:2:5
  |
2 | use std::collections::BinaryHeap;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: value assigned to `t` is never read
  --> Main.rs:10:17
   |
10 |         let mut t = 0;
   |                 ^
   |
   = note: `#[warn(unused_assignments)]` on by default
   = help: maybe it is overwritten before being read?

warning: unused variable: `cluster_ids`
   --> Main.rs:134:5
    |
134 |     cluster_ids: &[usize],
    |     ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_cluster_ids`
    |
    = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `n`
   --> Main.rs:211:10
    |
211 |     let (n, m, planets) = read_input();
    |          ^ help: if this is intentional, prefix it with an underscore: `_n`

warning: 5 warnings emitted

ソースコード

diff #
プレゼンテーションモードにする

use std::cmp::Reverse;
use std::collections::BinaryHeap;
static mut XORSHIFT1: u128 = 123456789;
static mut XORSHIFT2: u128 = 362436069;
static mut XORSHIFT3: u128 = 521288629;
static mut XORSHIFT4: u128 = 88675123;
fn xorshift() -> u128 {
unsafe {
let mut t = 0;
t = XORSHIFT1 ^ (XORSHIFT1 << 11u128);
XORSHIFT1 = XORSHIFT2;
XORSHIFT2 = XORSHIFT3;
XORSHIFT3 = XORSHIFT4;
XORSHIFT4 = (XORSHIFT4 ^ (XORSHIFT4 >> 19u128)) ^ (t ^ (t >> 8u128));
t
}
}
fn read_input() -> (usize, usize, Vec<(i32, i32)>) {
let (n, m) = {
let mut s = String::new();
std::io::stdin().read_line(&mut s).unwrap();
let s = s.trim_end().to_owned();
let mut ws = s.split_whitespace();
let n: usize = ws.next().unwrap().parse().unwrap();
let m: usize = ws.next().unwrap().parse().unwrap();
(n, m)
};
let mut xy = vec![];
for _ in 0..n {
let mut s = String::new();
std::io::stdin().read_line(&mut s).unwrap();
let s = s.trim_end().to_owned();
let mut ws = s.split_whitespace();
let a: i32 = ws.next().unwrap().parse().unwrap();
let b: i32 = ws.next().unwrap().parse().unwrap();
xy.push((a, b));
}
(n, m, xy)
}
const MAX_X: i32 = 1000;
type Point = (i32, i32);
// fn dist(p: &Point, q: &Point) -> i32 {
// (((p.0 - q.0) * (p.0 - q.0) + (p.1 - q.1) * (p.1 - q.1)) as f64).sqrt() as i32
// }
fn dist_powered(p: &Point, q: &Point) -> i32 {
(p.0 - q.0) * (p.0 - q.0) + (p.1 - q.1) * (p.1 - q.1)
}
fn kmeans(points: &[Point], k: usize, max_iter: usize) -> (Vec<Point>, Vec<usize>) {
let n = points.len();
let mut centors = Vec::with_capacity(k);
for _ in 0..k {
centors.push((
(xorshift() as i32).abs() % (MAX_X + 1),
(xorshift() as i32).abs() % (MAX_X + 1),
));
}
let mut cluster_ids = vec![0; n];
let mut cluster_sizes = vec![0; k];
cluster_sizes[0] = n as i32;
let mut updated = false;
for loop_count in 0..max_iter {
//
for i in 0..n {
let mut nearest_centor_id = 0;
let mut nearest_centor_distance = dist_powered(&points[i], &centors[0]);
for j in 1..k {
let distance = dist_powered(&points[i], &centors[j]);
if distance < nearest_centor_distance {
nearest_centor_distance = distance;
nearest_centor_id = j;
}
}
if nearest_centor_id != cluster_ids[i] {
cluster_sizes[cluster_ids[i]] -= 1;
cluster_ids[i] = nearest_centor_id;
cluster_sizes[nearest_centor_id] += 1;
updated = true;
}
}
//
let mut dxs = vec![0; k];
let mut dys = vec![0; k];
for i in 0..n {
let cid = cluster_ids[i];
dxs[cid] += points[i].0 - centors[cid].0;
dys[cid] += points[i].1 - centors[cid].1;
}
for i in 0..k {
if cluster_sizes[i] == 0 {
continue;
}
centors[i].0 += dxs[i] / cluster_sizes[i];
centors[i].1 += dys[i] / cluster_sizes[i];
}
if !updated {
eprintln!("kmeans loop breaked at loop {}", loop_count);
break;
}
}
(centors, cluster_ids)
}
// fn tsp_dp(points:&[Point])->Vec<usize>{
// let n = points.len();
// let mut dp = vec![]
// }
const ALPHA: i32 = 5;
fn get_cost_coefficient(t1: usize, t2: usize) -> i32 {
if t1 == PLANET {
if t2 == PLANET {
ALPHA * ALPHA
} else {
ALPHA
}
} else {
if t2 == PLANET {
ALPHA
} else {
1
}
}
}
const PLANET: usize = 1;
const STATION: usize = 2;
fn search_path(
stations: &[Point],
planets: &[Point],
cluster_ids: &[usize],
) -> Vec<(usize, usize)> {
let n = planets.len();
let m = stations.len();
//
let mut next = vec![vec![0; n + m]; n + m];
for i in 0..n + m {
for j in 0..n + m {
next[i][j] = j;
}
}
let mut dist = vec![vec![i32::MAX / 4; n + m]; n + m];
for i in 0..n + m {
let p = if i < n { planets[i] } else { stations[i - n] };
let tp = if i < n { PLANET } else { STATION };
for j in 0..n + m {
let q = if j < n { planets[j] } else { stations[j - n] };
let tq = if i < n { PLANET } else { STATION };
dist[i][j] = get_cost_coefficient(tp, tq) * dist_powered(&p, &q);
}
}
for k in 0..n + m {
for i in 0..n + m {
for j in 0..n + m {
if dist[i][k] + dist[k][j] < dist[i][j] {
dist[i][j] = dist[i][k] + dist[k][j];
next[i][j] = next[i][k];
}
}
}
}
//
let mut path = vec![(PLANET, 0)];
let mut visited = vec![false; planets.len()];
visited[0] = true;
let mut count_visited_planets = 1;
let mut cur_id = 0;
while count_visited_planets < planets.len() {
//
let mut nearest_distance = i32::MAX;
let mut nearest = (PLANET, 0);
for i in 0..planets.len() {
if visited[i] {
continue;
}
// let distance =
// get_cost_coefficient(cur_type, PLANET) * dist_powered(&cur_point, &planets[i]);
if dist[cur_id][i] < nearest_distance {
nearest_distance = dist[cur_id][i];
nearest = (PLANET, i);
}
}
//
if nearest.0 == PLANET {
count_visited_planets += 1;
visited[nearest.1] = true;
//
let mut cur = cur_id;
while cur != nearest.1 {
cur = next[cur][nearest.1];
path.push((if cur < n { PLANET } else { STATION }, cur % n));
}
}
path.push(nearest);
cur_id = nearest.1;
}
path.push((PLANET, 0));
path
}
fn main() {
let (n, m, planets) = read_input();
let (stations, cluster_ids) = kmeans(&planets, m, 1000);
eprintln!("stations: {:?}", stations);
let path = search_path(&stations, &planets, &cluster_ids);
assert!(path.len() <= 100000);
for (x, y) in stations.iter() {
println!("{} {}", x, y);
}
println!("{}", path.len());
for (t, i) in path.iter() {
println!("{} {}", t, i + 1);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_kmeans() {
let points = vec![(10, 10), (1000, 1000), (10, 5), (10, 6)];
let (centors, cluster_id) = kmeans(&points, 2, 100);
eprintln!("centors:{:?}", centors);
eprintln!("cluster_id:{:?}", cluster_id);
assert_eq!(cluster_id[0], cluster_id[2]);
assert_eq!(cluster_id[0], cluster_id[3]);
assert_eq!(centors[cluster_id[0]], (10, 7));
assert_eq!(centors[cluster_id[1]], (1000, 1000));
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0