제출 #1278550

#제출 시각아이디문제언어결과실행 시간메모리
1278550g4yuhg철인 이종 경기 (APIO18_duathlon)C++20
100 / 100
95 ms38184 KiB
//Huyduocdithitp
#include<bits/stdc++.h>
typedef long long ll;
#define endl '\n'
#define fi first
#define se second
#define pii pair<ll,ll>
#define N 800010
#define LOG 18
using namespace std;

// nen lai thanh cac bcc, cac dinh goc u -> bcc cua no ra do thi moi 
// voi moi dinh dac biet, u-v, ta gia su cat canh u-v => moi cap 2 dinh S F o cay con goc v, muon noi len u roi di xuong
// se bi sai => tru di luong do la duoc
// ans ban dau la tat ca cac cap co the den duoc voi nhau

const ll inf = 1e9;

bool ghuy4g;

ll n, m, num[N], low[N], timeDfs, bcc, ans, cur;
vector<ll> adj[N], p[N], adj3[N];

ll mp[N];

stack<pii> st;

void dfs(ll u, ll parent) {
	num[u] = low[u] = ++ timeDfs;
	for (auto v : adj[u]) {
		if (v == parent) continue;
		if (num[v]) {
			low[u] = min(low[u], num[v]);
		}
		else {
			st.push({u, v});
			dfs(v, u);
			low[u] = min(low[u], low[v]);
			if (low[v] >= num[u]) {
				pii edge;
				bcc ++ ;
				while (true) {
					edge = st.top();
					ll x = edge.fi, y = edge.se;
					if (mp[x] != bcc) {
						mp[x] = bcc;
						p[bcc].push_back(x);
					}
					if (mp[y] != bcc) {
						mp[y] = bcc;
						p[bcc].push_back(y);
					}
					st.pop();
					if (edge == make_pair(u, v)) {
						break;
					}
				}
			}
		}
	}
}

ll vst[N], dem = 0, sz[N];

void dfs2(ll u) {
	vst[u] = 1;
	dem ++ ;
	for (auto v : adj[u]) {
		if (vst[v]) continue;
		dfs2(v);
	}
}

void dfs3(ll u, ll parent) {
	vst[u] = 1;
	if (u <= n) sz[u] = 1;
	for (auto v : adj3[u]) {
		if (v == parent) continue;
		dfs3(v, u);
		sz[u] += sz[v];
	}
}

void dfs4(ll u, ll parent, ll goc) {
	for (auto v : adj3[u]) {
		if (v == parent) {
			if (u > n) {
				ll xet = goc - sz[u];
				ans -= ( adj3[u].size() - 1 ) * xet * (xet - 1);
			}
			continue;
		}
		dfs4(v, u, goc);
		//cout << u << " -> " << v << endl;
		if (u > n) {
			//cout << "node " << u << " " << v << " " << sz[v] << " " << ( adj3[u].size() ) << endl;
			ans -= ( adj3[u].size() - 1 ) * sz[v] * (sz[v] - 1);
		}
	}
}

void pre() {
	for (int i = 1; i <= n; i ++) {
		if (num[i] == 0) {
			dfs(i, i);
		}
	}
	for (int i = 1; i <= n; i ++) {
		if (vst[i] == 0) {
			dem = 0;
			dfs2(i);
			ans += dem * (dem - 1) * (dem - 2);
		}
	}
	//cout << ans << endl;
	for (int i = 1; i <= bcc; i ++) {
		cur ++ ;
		for (auto u : p[i]) {
			adj3[u].push_back(n + i);
			adj3[n + i].push_back(u);
			//cout << u << " " << n + i << endl;
		}
	}
	for (int i = 1; i <= cur; i ++) {
		vst[i] = 0;
	}
	for (int i = 1; i <= cur; i ++) {
		if (vst[i] == 0) {
			dfs3(i, i);
			dfs4(i, i, sz[i]);
		}
	}
	cout << ans;
}

bool klinh;

signed main() {
	//freopen("test.inp", "r", stdin);
	//freopen("test.out", "w", stdout);
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> m;
	cur = n;
	for (int i = 1; i <= m; i ++) {
		ll u, v;
		cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	
	pre();
	
	cerr << fabs(&klinh - &ghuy4g) / double(1024 * 1024);
	
	return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...