bzoj3714 [PA2014]Kuglarz 最小生成树
题面:
魔术师的桌子上有$n$个杯子排成一行,编号为$1,2,…,n$,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。
花费$c_ij$元,魔术师就会告诉你杯子$i,i+1,…,j$底下藏有球的总数的奇偶性。
采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?
我们可以把前$i$个杯子的球的奇偶关系看做一个点$S[i]$
那么,原题相当于最小生成树
使用$prim$算法可以做到$O(n^2)$
#include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> namespace remoon { #define re register #define de double #define le long double #define ri register int #define ll long long #define sh short #define pii pair<int, int> #define mp make_pair #define pb push_back #define tpr template <typename ra> #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++) #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --) extern inline char gc() { static char RR[23456], *S = RR + 23333, *T = RR + 23333; if(S == T) fread(RR, 1, 23333, stdin), S = RR; return *S ++; } inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } int wr[50], rw; #define pc(iw) putchar(iw) tpr inline void write(ra o, char c = '\n') { if(!o) pc('0'); if(o < 0) o = -o, pc('-'); while(o) wr[++ rw] = o % 10, o /= 10; while(rw) pc(wr[rw --] + '0'); pc(c); } tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; } tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; } tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; } } using namespace std; using namespace remoon; #define sid 2005 int n; ll ans; int vis[sid], low[sid], who[sid]; int w[sid][sid]; inline void MST() { vis[1] = 1; rep(i, 1, n + 1) low[i] = 1e9 + 5; rep(i, 2, n + 1) if(!vis[i] && ckmin(low[i], w[1][i])) who[i] = 1; rep(t, 1, n) { int nv = -1, dis = 1e9; rep(i, 1, n + 1) if(!vis[i] && ckmin(dis, low[i])) nv = i; ans += dis; vis[nv] = 1; rep(i, 1, n + 1) if(!vis[i] && ckmin(low[i], w[nv][i])) who[i] = nv; } write(ans); } int main() { n = read(); memset(w, 127, sizeof(w)); rep(i, 1, n) rep(j, i, n) w[j + 1][i] = w[i][j + 1] = read(); MST(); return 0; }
喵喵喵?喵喵喵! 喵喵喵......