Skip to content

Commit 27bd26e

Browse files
committed
1st solution
1 parent a24a47d commit 27bd26e

File tree

9 files changed

+1011
-0
lines changed

9 files changed

+1011
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target/
2+
*.csv

Cargo.lock

+48
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "santa17"
3+
version = "0.1.0"
4+
authors = ["wata"]
5+
6+
[dependencies]
7+
rand = "0.3"

src/bin/score.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
extern crate santa17;
2+
3+
use santa17::*;
4+
5+
fn main() {
6+
let g = construct_graph();
7+
let ps = read_solution(&std::env::args().nth(1).unwrap());
8+
let mut count = vec![0; N2];
9+
for i in 0..N1 {
10+
if ps[i] != !0 {
11+
count[ps[i]] += 1;
12+
}
13+
}
14+
for j in 0..N2 {
15+
assert!(count[j] <= 1000);
16+
}
17+
let mut err = false;
18+
for i in 0..K/2 {
19+
if ps[i * 2] != ps[i * 2 + 1] || ps[i * 2] == !0 {
20+
err = true;
21+
}
22+
}
23+
if err {
24+
println!("error!");
25+
}
26+
let mut cost = 0;
27+
for i in 0..N1 {
28+
for &(j, w) in &g[i] {
29+
if j == ps[i] {
30+
cost += w;
31+
}
32+
}
33+
}
34+
println!("{}", cost_to_score(cost));
35+
println!("{}", cost);
36+
}

src/bin/solve.rs

+209
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
extern crate santa17;
2+
extern crate rand;
3+
4+
use santa17::*;
5+
use santa17::common::*;
6+
use rand::Rng;
7+
8+
fn init(g: &Vec<Vec<(usize, i64)>>, g2: &Vec<Vec<(usize, i64)>>) -> Vec<usize> {
9+
if std::fs::File::open("ub.csv").is_ok() {
10+
return read_solution("ub.csv");
11+
}
12+
let mut ps = vec![!0; N1];
13+
let mut count = vec![0; N2];
14+
let mut mcf = mincostcirculation::Graph::new(N1 + N2 + 1);
15+
let r = N1 + N2;
16+
for i in 0..K {
17+
if i / 2 == 1802 { continue }//
18+
mcf.add(r, i, 1, 0);
19+
for &(j, w) in &g2[i / 2] {
20+
mcf.add(i, N1 + j, 1, w);
21+
}
22+
}
23+
for i in K..N1 {
24+
mcf.add(r, i, 1, 0);
25+
for &(j, w) in &g[i] {
26+
mcf.add(i, N1 + j, 1, w);
27+
}
28+
}
29+
for j in 0..N2 {
30+
mcf.add(N1 + j, r, 1000, 0);
31+
}
32+
mcf.solve();
33+
for i in 0..N1 {
34+
for &e in &mcf.es[i] {
35+
if N1 <= e.to && e.to < r && e.cap == 0 {
36+
let j = e.to - N1;
37+
ps[i] = j;
38+
count[j] += 1;
39+
}
40+
}
41+
}
42+
write_solution(&ps, "ub.csv");
43+
ps
44+
}
45+
46+
fn main() {
47+
let g = construct_graph();
48+
let g2: Vec<Vec<_>> = (0..K/2).map(|i| merge(&g[i * 2], &g[i * 2 + 1]).into_iter().map(|(j, w)| (j, w / 2)).collect()).collect();
49+
let mut ps = init(&g, &g2);
50+
let mut cost = 0;
51+
for i in 0..K {
52+
cost += get_cost(&g2[i / 2], ps[i]).unwrap_or_default();
53+
}
54+
for i in K..N1 {
55+
cost += get_cost(&g[i], ps[i]).unwrap_or_default();
56+
}
57+
eprintln!("{}", cost);
58+
eprintln!("{:.8}", cost_to_score(cost));
59+
for i in 0..K/2 {
60+
if ps[i * 2] != ps[i * 2 + 1] {
61+
eprintln!("mismatch: {} {:?} {:?}", i, get_cost(&g2[i], ps[i * 2]), get_cost(&g2[i], ps[i * 2 + 1]));
62+
let i2 = if ps[i * 2] != 0 {
63+
i * 2
64+
} else if ps[i * 2 + 1] != 0 {
65+
i * 2 + 1
66+
} else {
67+
!0
68+
};
69+
if i2 != !0 {
70+
let mut t = !0;
71+
let mut max = get_cost(&g2[i], ps[i2]).unwrap();
72+
for k in K..N1 {
73+
if ps[k] == ps[i2] && max.setmax(get_cost(&g[k], ps[k]).unwrap()) {
74+
t = k;
75+
}
76+
}
77+
if t != !0 {
78+
eprintln!("{}", max);
79+
ps[t] = !0;
80+
let j = ps[i2];
81+
ps[i * 2] = j;
82+
ps[i * 2 + 1] = j;
83+
} else {
84+
ps[i * 2] = !0;
85+
ps[i * 2 + 1] = !0;
86+
}
87+
} else {
88+
ps[i * 2] = !0;
89+
ps[i * 2 + 1] = !0;
90+
}
91+
}
92+
}
93+
let mut count = vec![0; N2];
94+
let mut cost = 0;
95+
for i in 0..N1 {
96+
if ps[i] != !0 {
97+
count[ps[i]] += 1;
98+
cost += get_cost(&g[i], ps[i]).unwrap_or_default();
99+
}
100+
}
101+
eprintln!("{:.8}", cost_to_score(cost));
102+
let mut n1 = 0;
103+
for i in 0..K/2 {
104+
if ps[i * 2] == !0 {
105+
n1 += 1;
106+
}
107+
}
108+
let mut n2 = 0;
109+
for j in 0..N2 {
110+
n2 += (1000 - count[j]) / 2;
111+
}
112+
eprintln!("{} {}", n1, n2);
113+
let mut min = 0;
114+
let mut rng = rand::XorShiftRng::new_unseeded();
115+
loop {
116+
let mut mcf = mincostflow::Graph::new(N1 + N2 + 4);
117+
let r = N1 + N2;
118+
let s = r + 1;
119+
let t = r + 2;
120+
let t2 = r + 3;
121+
for i in K..N1 {
122+
if ps[i] == !0 {
123+
mcf.add(r, i, 1, 0);
124+
} else {
125+
mcf.add(i, r, 1, 0);
126+
}
127+
for &(j, w) in &g[i] {
128+
if j != ps[i] {
129+
mcf.add(i, N1 + j, 1, w);
130+
} else {
131+
mcf.add(N1 + j, i, 1, -w);
132+
}
133+
}
134+
}
135+
for j in 0..N2 {
136+
if count[j] % 2 == 1 {
137+
if rng.gen() {
138+
mcf.add(s, N1 + j, 1, 0);
139+
} else {
140+
mcf.add(N1 + j, t, 1, 0);
141+
}
142+
}
143+
}
144+
mcf.add(t, t2, n1 - n2, 0);
145+
if mcf.solve(s, t2, true).0 != n1 - n2 {
146+
eprintln!("failed");
147+
continue;
148+
}
149+
let mut ps = ps.clone();
150+
for i in K..N1 {
151+
ps[i] = !0;
152+
for &e in &mcf.es[i] {
153+
if N1 <= e.to && e.to < r && e.cap == 0 {
154+
let j = e.to - N1;
155+
ps[i] = j;
156+
}
157+
}
158+
}
159+
let mut count = vec![0; N2];
160+
let mut cost = 0;
161+
for i in 0..N1 {
162+
if ps[i] != !0 {
163+
count[ps[i]] += 1;
164+
cost += get_cost(&g[i], ps[i]).unwrap_or_default();
165+
}
166+
}
167+
let mut n1 = 0;
168+
for i in 0..K/2 {
169+
if ps[i * 2] == !0 {
170+
n1 += 1;
171+
}
172+
}
173+
let mut n2 = 0;
174+
for j in 0..N2 {
175+
n2 += (1000 - count[j]) / 2;
176+
}
177+
eprintln!("{} {}", n1, n2);
178+
assert!(n1 <= n2);
179+
eprintln!("{:.8}", cost_to_score(cost));
180+
if !min.setmin(cost) {
181+
continue;
182+
}
183+
eprintln!("updated: {}", cost);
184+
for i in 0..K/2 {
185+
if ps[i * 2] == !0 {
186+
for j in 0..N2 {
187+
if count[j] <= 998 {
188+
ps[i * 2] = j;
189+
ps[i * 2 + 1] = j;
190+
count[j] += 2;
191+
break;
192+
}
193+
}
194+
}
195+
}
196+
for i in 0..N1 {
197+
if ps[i] == !0 {
198+
for j in 0..N2 {
199+
if count[j] < 1000 {
200+
ps[i] = j;
201+
count[j] += 1;
202+
break;
203+
}
204+
}
205+
}
206+
}
207+
write_solution(&ps, "out.csv");
208+
}
209+
}

src/common.rs

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#[macro_export]
2+
macro_rules! debug {
3+
($($v:expr),*) => { {
4+
use ::std::io::Write;
5+
$(let _ = write!(::std::io::stderr(), "{} = {:?} ", stringify!($v), $v);)*
6+
let _ = writeln!(::std::io::stderr(), "@ {}:{}", file!(), line!());
7+
} }
8+
}
9+
10+
#[macro_export]
11+
macro_rules! mat {
12+
($e:expr) => { $e };
13+
($e:expr; $d:expr $(; $ds:expr)*) => { vec![mat![$e $(; $ds)*]; $d] };
14+
}
15+
16+
pub trait SetMin {
17+
fn setmin(&mut self, v: Self) -> bool;
18+
}
19+
20+
impl<T> SetMin for T where T: PartialOrd {
21+
#[inline]
22+
fn setmin(&mut self, v: T) -> bool {
23+
*self > v && { *self = v; true }
24+
}
25+
}
26+
27+
pub trait SetMax {
28+
fn setmax(&mut self, v: Self) -> bool;
29+
}
30+
31+
impl<T> SetMax for T where T: PartialOrd {
32+
#[inline]
33+
fn setmax(&mut self, v: T) -> bool {
34+
*self < v && { *self = v; true }
35+
}
36+
}
37+
38+
#[macro_export]
39+
macro_rules! ok {
40+
($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
41+
$a$([$i])*.$f($($t),*)
42+
};
43+
($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
44+
let t = $e;
45+
ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
46+
} };
47+
}
48+
49+
macro_rules! impl_cmp {
50+
($name:ident $(<$($t:ident),*>)*; |$x:ident, $y:ident| $e:expr; $($w:tt)*) => {
51+
impl $(<$($t),*>)* Ord for $name $(<$($t),*>)* $($w)* {
52+
#[inline]
53+
fn cmp(&self, $y: &Self) -> ::std::cmp::Ordering {
54+
let $x = &self;
55+
$e
56+
}
57+
}
58+
impl $(<$($t),*>)* PartialOrd for $name $(<$($t),*>)* $($w)* {
59+
#[inline]
60+
fn partial_cmp(&self, a: &Self) -> Option<::std::cmp::Ordering> {
61+
Some(self.cmp(a))
62+
}
63+
}
64+
impl $(<$($t),*>)* PartialEq for $name $(<$($t),*>)* $($w)* {
65+
#[inline]
66+
fn eq(&self, a: &Self) -> bool {
67+
self.cmp(a) == ::std::cmp::Ordering::Equal
68+
}
69+
}
70+
impl $(<$($t),*>)* Eq for $name $(<$($t),*>)* $($w)* {}
71+
}
72+
}
73+
74+
#[derive(Clone, Copy, Debug, Default, Hash)]
75+
pub struct Tot<T: PartialOrd>(pub T);
76+
impl_cmp!(Tot<T>; |a, b| a.0.partial_cmp(&b.0).unwrap(); where T: PartialOrd);
77+
78+
#[derive(Clone, Copy, Debug, Default, Hash)]
79+
pub struct Rev<T: PartialOrd>(pub T);
80+
impl_cmp!(Rev<T>; |a, b| b.0.partial_cmp(&a.0).unwrap(); where T: PartialOrd);

0 commit comments

Comments
 (0)