1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll N = 1e5 + 10;
ll T, n, m, head[N], edge_cnt, fa[N], low[N], dfn[N], tar_cnt, isbri[N], siz[N], ans; struct edge { ll nxt, v; } e[N << 1];
void add_edge(ll u, ll v) { e[++edge_cnt].nxt = head[u]; head[u] = edge_cnt; e[edge_cnt].v = v; }
void Tarjan(ll u, ll pre) { fa[u] = pre; siz[u] = 1; low[u] = dfn[u] = ++tar_cnt; for (int i = head[u]; i; i = e[i].nxt) { ll v = e[i].v; if (!dfn[v]) { Tarjan(v, u); siz[u] += siz[v]; low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) isbri[v] = 1; } else if (dfn[v] < dfn[u] && v != pre) low[u] = min(low[u], dfn[v]); } }
void WORK() { scanf("%lld%lld", &n, &m); memset(dfn, 0, sizeof(ll) * (n + 10)); memset(low, 0, sizeof(ll) * (n + 10)); tar_cnt = edge_cnt = 0; memset(fa, 0, sizeof(ll) * (n + 10)); memset(isbri, 0, sizeof(ll) * (n + 10)); memset(siz, 0, sizeof(ll) * (n + 10)); memset(head, 0, sizeof(ll) * (n + 10)); for (int i = 1; i <= m; i++) { ll u, v; scanf("%lld%lld", &u, &v); add_edge(u, v); add_edge(v, u); } Tarjan(1, 0); ans = n; for (int i = 1; i <= n; i++) if (isbri[i]) ans = min(ans, max(siz[i], n - siz[i])); printf("%lld\n", ans * (ans - 1) / 2 + (n - ans) * (n - ans - 1) / 2); }
int main() { scanf("%lld", &T); while (T--) WORK(); return 0; }
|