結果
| 問題 |
No.114 遠い未来
|
| ユーザー |
|
| 提出日時 | 2017-08-09 10:27:18 |
| 言語 | D (dmd 2.109.1) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,777 bytes |
| コンパイル時間 | 999 ms |
| コンパイル使用メモリ | 123,772 KB |
| 実行使用メモリ | 13,888 KB |
| 最終ジャッジ日時 | 2024-06-12 21:19:20 |
| 合計ジャッジ時間 | 23,651 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 9 WA * 1 TLE * 1 -- * 14 |
ソースコード
import std.algorithm, std.conv, std.range, std.stdio, std.string;
alias Graph!(int, size_t) graph;
void main()
{
auto rd1 = readln.split.to!(size_t[]), n = rd1[0], m = rd1[1], t = rd1[2];
auto e = new Edge[](m);
foreach (i; 0..m) {
auto rd2 = readln.splitter;
auto src = rd2.front.to!size_t-1; rd2.popFront();
auto dst = rd2.front.to!size_t-1; rd2.popFront();
e[i] = Edge(src, dst, rd2.front.to!int);
}
auto v = t.iota.map!(_ => readln.chomp.to!size_t-1).array;
v.sort();
auto calc1()
{
auto g = new int[][](n, n);
foreach (ref r; g) r[] = graph.inf;
foreach (i; 0..n) g[i][i] = 0;
foreach (ref ei; e) g[ei.s][ei.t] = g[ei.t][ei.s] = ei.w;
return graph.minimumSteinerTree(v, g);
}
auto calc2()
{
auto cb = ulong(0);
foreach (vi; v) cb = cb.bitSet(vi);
auto w = n.iota.setDifference(v).array;
e.sort!"a.w < b.w";
auto u = n - t, ans = int.max;
foreach (i; 0..1<<u) {
auto cc = cb;
foreach (j; 0..u)
if (i.bitTest(j)) cc = cc.bitSet(w[j]);
auto ec = e.filter!(ei => cc.bitTest(ei.s) && cc.bitTest(ei.t));
auto uf = UnionFind!size_t(n), r = 0;
auto check()
{
auto c = n;
foreach (i; 0..n)
if (cc.bitTest(i)) {
auto d = uf.find(i);
if (c != n && c != d) return false;
c = d;
}
return true;
}
foreach (eci; ec) {
if (!uf.isSame(eci.s, eci.t)) {
uf.unite(eci.s, eci.t);
r += eci.w;
}
}
if (check) ans = min(ans, r);
}
return ans;
}
writeln(t <= 14 ? calc1 : calc2);
}
pragma(inline) {
pure bool bitTest(T)(T n, size_t i) { return (n & (T(1) << i)) != 0; }
pure T bitSet(T)(T n, size_t i) { return n | (T(1) << i); }
pure T bitReset(T)(T n, size_t i) { return n & ~(T(1) << i); }
pure T bitComp(T)(T n, size_t i) { return n ^ (T(1) << i); }
import core.bitop;
pure int bsf(T)(T n) { return core.bitop.bsf(ulong(n)); }
pure int bsr(T)(T n) { return core.bitop.bsr(ulong(n)); }
pure int popcnt(T)(T n) { return core.bitop.popcnt(ulong(n)); }
}
struct Edge { size_t s, t; int w; }
template Graph(Wt, Node, Wt _inf = 10 ^^ 9)
{
import std.algorithm, std.array;
const inf = _inf;
Wt minimumSteinerTree(Node[] t, Wt[][] g)
{
auto n = g.length, nt = t.length;
auto d = g.map!(i => i.dup).array;
foreach (k; 0..n)
foreach (i; 0..n)
foreach (j; 0..n)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
auto opt = new Wt[][](1<<nt, n);
foreach (s; 0..1<<nt)
opt[s][] = inf;
foreach (p; 0..nt)
foreach (q; 0..n)
opt[1<<p][q] = d[t[p]][q];
foreach (s; 1..1<<nt)
if (s & (s-1)) {
foreach (p; 0..n)
foreach (e; 0..s)
if ((e | s) == s) opt[s][p] = min(opt[s][p], opt[e][p] + opt[s-e][p]);
foreach (p; 0..n)
foreach (q; 0..n)
opt[s][p] = min(opt[s][p], opt[s][q] + d[p][q]);
}
Wt ans = inf;
foreach (s; 0..1<<nt)
foreach (q; 0..n)
ans = min(ans, opt[s][q] + opt[$-1-s][q]);
return ans;
}
}
struct UnionFind(T)
{
import std.algorithm, std.range;
T[] p; // parent
const T s; // sentinel
const T n;
this(T n)
{
this.n = n;
p = new T[](n);
s = n + 1;
p[] = s;
}
T find(T i)
{
if (p[i] == s) {
return i;
} else {
p[i] = find(p[i]);
return p[i];
}
}
void unite(T i, T j)
{
auto pi = find(i), pj = find(j);
if (pi != pj) p[pj] = pi;
}
bool isSame(T i, T j) { return find(i) == find(j); }
auto groups()
{
auto g = new T[][](n);
foreach (i; 0..n) g[find(i)] ~= i;
return g.filter!(l => !l.empty);
}
}