SRM 733 Div 1 爆零记
开场写easy(有预感要FST)
然后medium就卡住了。
我只知道$n$个点的生成树个数是$n^{n-2}$
接下来直接狗带……
$Problem 250pts$
水题,直接枚举然后记录答案(我大概是因为精度问题被HACK了)
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
#define MP make_pair
#define fi first
#define se second
typedef long long LL;
typedef pair <int, int> PII;
typedef pair <PII, PII> PIIII;
const double eps = 1e-12;
class MinimizeAbsoluteDifferenceDiv1 {
public:
vector<int> findTuple(vector<int> x) {
PIIII ans = MP(MP(1e9, 1e9), MP(1e9, 1e9));
double ff = 1e9;
rep(i, 0, 4){
rep(j, 0, 4){
if (i == j) continue;
rep(k, 0, 4){
if (k == i || k == j) continue;
rep(l, 0, 4){
if (l == i || l == j || l == k) continue;
double aa = fabs(1.00 * x[i] / x[j] - 1.00 * x[k] / x[l]);
if (aa < ff - eps){
ff = aa;
ans = MP(MP(i, j), MP(k, l));
}
}
}
}
}
vector <int> ret;
ret.push_back(ans.fi.fi);
ret.push_back(ans.fi.se);
ret.push_back(ans.se.fi);
ret.push_back(ans.se.se);
return ret;
}
};
$Problem 500Pts$
给定一个边集,求符合条件的生成树的个数(生成树的边必须包含这个边集,点数 <= $1000$)
比赛的时候差一点就推出公式乐……不知道为什么
设连通块个数为$s$,每个连通块的点数的乘积为$m$,
那么答案为$mn^{s-2}$
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 1e3 + 10; const LL mod = 987654323; class BuildingSpanningTreesDiv1 { public: int father[N], c[N]; inline LL Pow(LL a, LL b, LL mod){ LL ret(1); for (; b; b >>= 1, (a *= a) %= mod) if (b & 1) (ret *= a) %= mod; return ret; } int getfather(int x){ return father[x] ? father[x] = getfather(father[x]) : x; } int getNumberOfSpanningTrees(int n, vector <int> a, vector <int> b) { int m = (int)a.size(); memset(father, 0, sizeof father); int block = n; rep(i, 0, m - 1){ int x = a[i], y = b[i]; int fx = getfather(x), fy = getfather(y); if (fx == fy) return 0; --block; father[fx] = fy; } memset(c, 0, sizeof c); rep(i, 1, n){ int x = getfather(i); ++c[x]; } vector <LL> v; rep(i, 1, n) if (c[i]) v.push_back(c[i]); if (block == 1) return 1; LL ans = Pow((LL)n, (LL)block - 2, mod); for (auto u : v) ans = ans * u % mod; return (int)ans; } };