Submission #1220291
Source Code Expand
/+ dub.sdl:
name "A"
dependency "dcomp" version=">=0.6.0"
+/
import std.stdio, std.algorithm, std.range, std.conv;
import std.typecons, std.math;
// import dcomp.foundation, dcomp.scanner;
// import dcomp.datastructure.unionfind;
int n;
double[2][] p;
double[] a;
double[] costs;
double calc(int f) {
alias Q = Tuple!(double, int, int);
Q[] edges;
foreach (i; 0..n) {
foreach (j; i+1..n) {
if (!(f & (1<<i))) continue;
if (!(f & (1<<j))) continue;
double u = 0;
u += (p[i][0]-p[j][0])*(p[i][0]-p[j][0]);
u += (p[i][1]-p[j][1])*(p[i][1]-p[j][1]);
edges ~= Q(sqrt(u), i, j);
}
}
edges.sort!"a[0]<b[0]";
auto uf = UnionFind(n);
double ans = 0;
foreach (e; edges) {
if (uf.same(e[1], e[2])) continue;
ans += e[0];
uf.merge(e[1], e[2]);
}
double sm = 0;
int co = 0;
foreach (i; 0..n) {
if (f & (1<<i)) {
co++;
sm += a[i];
}
}
return max(0.0, (sm-ans))/co;
}
int main() {
auto sc = new Scanner(stdin);
sc.read(n);
p = new double[2][n];
a = new double[n];
foreach (i; 0..n) {
sc.read(p[i][0], p[i][1], a[i]);
}
costs = new double[1<<n];
iota(1, 1<<n).each!(i => costs[i] = calc(i));
// writeln(costs);
auto dp = new double[1<<n];
foreach (i; 1..(1<<n)) {
dp[i] = costs[i];
for (auto j = 0; j < i; j = ((j|~i)+1)&i) {
if (j == 0) continue;
dp[i] = max(dp[i], min(dp[j], costs[i^j]));
}
}
writefln("%.20f", dp[(1<<n)-1]);
return 0;
}
/* IMPORT /home/yosupo/Program/dcomp/source/dcomp/foundation.d */
// module dcomp.foundation;
//fold(for old compiler)
static if (__VERSION__ <= 2070) {
template fold(fun...) if (fun.length >= 1) {
auto fold(R, S...)(R r, S seed) {
import std.algorithm : reduce;
static if (S.length < 2) {
return reduce!fun(seed, r);
} else {
import std.typecons : tuple;
return reduce!fun(tuple(seed), r);
}
}
}
unittest {
import std.stdio;
auto l = [1, 2, 3, 4, 5];
assert(l.fold!"a+b"(10) == 25);
}
}
version (X86) static if (__VERSION__ < 2071) {
int bsf(ulong v) {
foreach (i; 0..64) {
if (v & (1UL << i)) return i;
}
return -1;
}
int bsr(ulong v) {
foreach_reverse (i; 0..64) {
if (v & (1UL << i)) return i;
}
return -1;
}
int popcnt(ulong v) {
int c = 0;
foreach (i; 0..64) {
if (v & (1UL << i)) c++;
}
return c;
}
}
/* IMPORT /home/yosupo/Program/dcomp/source/dcomp/scanner.d */
// module dcomp.scanner;
class Scanner {
import std.stdio : File;
import std.conv : to;
import std.range : front, popFront, array, ElementType;
import std.array : split;
import std.traits : isSomeChar, isStaticArray, isArray;
import std.algorithm : map;
File f;
this(File f) {
this.f = f;
}
char[512] lineBuf;
char[] line;
private bool succ() {
import std.range.primitives : empty, front, popFront;
import std.ascii : isWhite;
while (true) {
while (!line.empty && line.front.isWhite) {
line.popFront;
}
if (!line.empty) break;
if (f.eof) return false;
line = lineBuf[];
f.readln(line);
}
return true;
}
private bool readSingle(T)(ref T x) {
import std.algorithm : findSplitBefore;
import std.string : strip;
import std.conv : parse;
if (!succ()) return false;
static if (isArray!T) {
alias E = ElementType!T;
static if (isSomeChar!E) {
//string or char[10] etc
//todo optimize
auto r = line.findSplitBefore(" ");
x = r[0].strip.dup;
line = r[1];
} else {
auto buf = line.split.map!(to!E).array;
static if (isStaticArray!T) {
//static
assert(buf.length == T.length);
}
x = buf;
line.length = 0;
}
} else {
x = line.parse!T;
}
return true;
}
int read(T, Args...)(ref T x, auto ref Args args) {
if (!readSingle(x)) return 0;
static if (args.length == 0) {
return 1;
} else {
return 1 + read(args);
}
}
}
unittest {
import std.path : buildPath;
import std.file : tempDir;
import std.algorithm : equal;
import std.stdio : File;
string fileName = buildPath(tempDir, "kyuridenanmaida.txt");
auto fout = File(fileName, "w");
fout.writeln("1 2 3");
fout.writeln("ab cde");
fout.writeln("1.0 1.0 2.0");
fout.close;
Scanner sc = new Scanner(File(fileName, "r"));
int a;
int[2] b;
char[2] c;
string d;
double e;
double[] f;
sc.read(a, b, c, d, e, f);
assert(a == 1);
assert(equal(b[], [2, 3]));
assert(equal(c[], "ab"));
assert(equal(d, "cde"));
assert(e == 1.0);
assert(equal(f, [1.0, 2.0]));
}
unittest {
import std.path : buildPath;
import std.file : tempDir;
import std.algorithm : equal;
import std.stdio : File, writeln;
import std.datetime;
string fileName = buildPath(tempDir, "kyuridenanmaida.txt");
auto fout = File(fileName, "w");
foreach (i; 0..1_000_000) {
fout.writeln(3*i, " ", 3*i+1, " ", 3*i+2);
}
fout.close;
writeln("Scanner Speed Test(3*1,000,000 int)");
StopWatch sw;
sw.start;
Scanner sc = new Scanner(File(fileName, "r"));
foreach (i; 0..500_000) {
int a, b, c;
sc.read(a, b, c);
assert(a == 3*i);
assert(b == 3*i+1);
assert(c == 3*i+2);
}
foreach (i; 500_000..700_000) {
int[3] d;
sc.read(d);
int a = d[0], b = d[1], c = d[2];
assert(a == 3*i);
assert(b == 3*i+1);
assert(c == 3*i+2);
}
foreach (i; 700_000..1_000_000) {
int[] d;
sc.read(d);
assert(d.length == 3);
int a = d[0], b = d[1], c = d[2];
assert(a == 3*i);
assert(b == 3*i+1);
assert(c == 3*i+2);
}
writeln(sw.peek.msecs, "ms");
}
/* IMPORT /home/yosupo/Program/dcomp/source/dcomp/datastructure/unionfind.d */
// module dcomp.datastructure.unionfind;
struct UnionFind {
import std.algorithm : map, swap, each;
import std.range : iota, array;
int[] id; // group id
int[][] groups; // group list
int count; // group count
this(int n) {
id = iota(n).array;
groups = iota(n).map!(a => [a]).array;
count = n;
}
void merge(int a, int b) {
if (same(a, b)) return;
count--;
int x = id[a], y = id[b];
if (groups[x].length < groups[y].length) swap(x, y);
groups[y].each!(a => id[a] = x);
groups[x] ~= groups[y];
groups[y] = [];
}
int[] group(int i) {
return groups[id[i]];
}
bool same(int a, int b) {
return id[a] == id[b];
}
}
unittest {
import std.algorithm : equal, sort;
auto uf = UnionFind(5);
assert(!uf.same(1, 3));
assert(uf.same(0, 0));
uf.merge(3, 2);
uf.merge(1, 1);
uf.merge(4, 2);
uf.merge(4, 3);
assert(uf.count == 3);
assert(uf.id[2] == uf.id[3]);
assert(uf.id[2] == uf.id[4]);
assert(equal(uf.group(0), [0]));
assert(equal(uf.group(1), [1]));
assert(equal(sort(uf.group(2)), [2, 3, 4]));
}
unittest {
import std.datetime, std.stdio, std.range;
// speed check
writeln("UnionFind Speed Test");
StopWatch sw;
sw.start;
UnionFind uf;
// line
uf = UnionFind(1_000_000);
foreach (i; 1..1_000_000) {
uf.merge(i-1, i);
}
// line(reverse)
uf = UnionFind(1_000_000);
foreach_reverse (i; 1..1_000_000) {
uf.merge(i-1, i);
}
// binary tree
uf = UnionFind(1_000_000);
foreach (lg; 1..20) {
int len = 1<<lg;
foreach (i; iota(0, 1_000_000-len/2, len)) {
uf.merge(i, i+len/2);
}
}
sw.stop;
writeln(sw.peek.msecs, "ms");
}
Submission Info
Submission Time |
|
Task |
E - Water Distribution |
User |
yosupo |
Language |
D (LDC 0.17.0) |
Score |
1000 |
Code Size |
8800 Byte |
Status |
AC |
Exec Time |
170 ms |
Memory |
3836 KB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
1000 / 1000 |
Status |
|
|
Set Name |
Test Cases |
Sample |
example0.txt, example1.txt |
All |
000.txt, 001.txt, 002.txt, 003.txt, 004.txt, 005.txt, 006.txt, 007.txt, 008.txt, 009.txt, 010.txt, 011.txt, 012.txt, 013.txt, 014.txt, 015.txt, 016.txt, 017.txt, 018.txt, 019.txt, 020.txt, 021.txt, 022.txt, 023.txt, 024.txt, 025.txt, 026.txt, 027.txt, 028.txt, 029.txt, 030.txt, 031.txt, 032.txt, 033.txt, 034.txt, 035.txt, 036.txt, 037.txt, 038.txt, 039.txt, 040.txt, 041.txt, 042.txt, 043.txt, example0.txt, example1.txt |
Case Name |
Status |
Exec Time |
Memory |
000.txt |
AC |
166 ms |
1788 KB |
001.txt |
AC |
169 ms |
1788 KB |
002.txt |
AC |
167 ms |
3836 KB |
003.txt |
AC |
168 ms |
1788 KB |
004.txt |
AC |
167 ms |
1788 KB |
005.txt |
AC |
170 ms |
1788 KB |
006.txt |
AC |
170 ms |
1788 KB |
007.txt |
AC |
166 ms |
3708 KB |
008.txt |
AC |
166 ms |
1788 KB |
009.txt |
AC |
167 ms |
1788 KB |
010.txt |
AC |
169 ms |
3452 KB |
011.txt |
AC |
166 ms |
1788 KB |
012.txt |
AC |
169 ms |
1788 KB |
013.txt |
AC |
168 ms |
1788 KB |
014.txt |
AC |
166 ms |
1788 KB |
015.txt |
AC |
169 ms |
1788 KB |
016.txt |
AC |
168 ms |
1788 KB |
017.txt |
AC |
168 ms |
1788 KB |
018.txt |
AC |
169 ms |
3452 KB |
019.txt |
AC |
167 ms |
1788 KB |
020.txt |
AC |
167 ms |
3452 KB |
021.txt |
AC |
166 ms |
3836 KB |
022.txt |
AC |
168 ms |
1788 KB |
023.txt |
AC |
169 ms |
3452 KB |
024.txt |
AC |
169 ms |
1788 KB |
025.txt |
AC |
166 ms |
1788 KB |
026.txt |
AC |
166 ms |
1788 KB |
027.txt |
AC |
166 ms |
1788 KB |
028.txt |
AC |
169 ms |
3324 KB |
029.txt |
AC |
168 ms |
1788 KB |
030.txt |
AC |
168 ms |
1788 KB |
031.txt |
AC |
168 ms |
1788 KB |
032.txt |
AC |
167 ms |
1788 KB |
033.txt |
AC |
168 ms |
1788 KB |
034.txt |
AC |
166 ms |
1788 KB |
035.txt |
AC |
166 ms |
1788 KB |
036.txt |
AC |
168 ms |
3580 KB |
037.txt |
AC |
169 ms |
1788 KB |
038.txt |
AC |
170 ms |
1788 KB |
039.txt |
AC |
168 ms |
3580 KB |
040.txt |
AC |
1 ms |
256 KB |
041.txt |
AC |
1 ms |
256 KB |
042.txt |
AC |
1 ms |
256 KB |
043.txt |
AC |
2 ms |
380 KB |
example0.txt |
AC |
1 ms |
256 KB |
example1.txt |
AC |
165 ms |
1788 KB |