This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 9;
int n, m;
vector<int> g[N];
// chain and cycle
namespace subtask3 {
bool check() {
for (int i = 1; i <= n; ++i)
if (g[i].size() > 2) return false;
return true;
}
int par[N];
int root(int u) { return par[u] < 0 ? u : par[u] = root(par[u]); }
void Union(int u, int v) {
if ((u = root(u)) == (v = root(v))) return;
if (par[u] > par[v]) swap(u, v);
par[u] += par[v];
par[v] = u;
}
bool f[N];
void solve() {
fill(par + 1, par + n + 1, -1);
for (int u = 1; u <= n; ++u)
for (int v : g[u]) Union(u, v);
for (int i = 1; i <= n; ++i)
if (g[i].size() == 1) f[root(i)] = true;
ll ans(0), sz;
for (int i = 1; i <= n; ++i) if (par[i] < 0) {
sz = -par[i];
ans += sz * (sz - 1) * (sz - 2) / (f[i] ? 3 : 1);
}
cout << ans << '\n';
}
}
// tree
namespace subtask45 {
int par[N];
int root(int u) { return par[u] < 0 ? u : par[u] = root(par[u]); }
bool Union(int u, int v) {
if ((u = root(u)) == (v = root(v))) return false;
if (par[u] > par[v]) swap(u, v);
par[u] += par[v];
par[v] = u;
return true;
}
bool check() {
fill(par + 1, par + n + 1, -1);
for (int u = 1; u <= n; ++u)
for (int v : g[u])
if (u < v && !Union(u, v)) return false;
return true;
}
ll ans;
int sz[N];
bool vis[N];
void dfs_sz(int u, int p) {
sz[u] = 1;
for (int v : g[u]) if (v != p) {
dfs_sz(v, u);
sz[u] += sz[v];
}
}
void dfs(int u, int p, int sz_n) {
vis[u] = true;
ans += (ll)(sz_n - sz[u]) * (sz[u] - 1) * 2;
ll sum(0);
for (int v : g[u]) if (v != p) {
ans += sum * sz[v] * 2;
sum += sz[v];
dfs(v, u, sz_n);
}
}
void solve() {
for (int u = 1; u <= n; ++u) if (!vis[u]) {
dfs_sz(u, 0);
dfs(u, 0, sz[u]);
}
cout << ans << '\n';
}
}
bool f[N];
int main() {
cin.tie(NULL)->sync_with_stdio(false);
cin >> n >> m;
for (int i = 0, u, v; i < m; ++i) {
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
if (subtask3::check())
subtask3::solve();
else if (subtask45::check())
subtask45::solve();
}
/** /\_/\
* (= ._.)
* / >0 \>1
**/
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |