2016-06-26 12:17:54
近期打的两场比赛,小结一下里面有趣的题。
1:TC SRM 693 div1 600pt
题意:给出一个k(<=1e9),让你造一个n(<=20)对点的二分图,点之间可以有重边,总边数为E(<=120),使得其完备匹配方案数为k。
思路:首先注意到可以有重边,这个很关键。其次,这种构造显然是拆分 k 为某个 base 进制,由于只有20对点,考虑用3进制,接下来yy一下。
※ 如下建图,边权即为该边建立的重边数。
※ 那么最右下角的黑点,就可以决定各个进制为上的数字了。
※ 比如最右下黑点与最左下白点建立 a 条边,就能构造出 a * base^3,以此类推。
※ 可以发现一旦最右下黑点与第 i 个白点匹配,那么 i+1 ~ n 号白点只能沿着斜向的边匹配 i ~ n-1 号黑点,而 1 ~ i-1 号白点可以匹配对应的黑点,形成 base^(i-1)。因此进制之间不冲突,形成加法关系。
class BipartiteConstruction { public: vector <int> construct(int K) { vector<int> ans; ans.PB(20); for(int i = 0; i < 19; ++i) for(int j = 0; j < 3; ++j) ans.PB(i * 20 + i); for(int i = 1; i < 20; ++i) ans.PB(i * 20 + i - 1); for(int i = 0; i < 20; ++i){ int v = K % 3; for(int j = 0; j < v; ++j) ans.PB(i * 20 + 19); K /= 3; } return ans; } };