結果

問題 No.922 東北きりきざむたん
ユーザー sigma425sigma425
提出日時 2019-11-09 10:26:19
言語 C++17
(gcc 13.2.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,120 bytes
コンパイル時間 2,478 ms
コンパイル使用メモリ 214,196 KB
実行使用メモリ 30,672 KB
最終ジャッジ日時 2023-10-13 07:00:36
合計ジャッジ時間 7,296 ms
ジャッジサーバーID
(参考情報)
judge11 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,352 KB
testcase_01 AC 1 ms
4,352 KB
testcase_02 AC 1 ms
4,352 KB
testcase_03 AC 1 ms
4,352 KB
testcase_04 AC 2 ms
4,352 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,352 KB
testcase_07 AC 2 ms
4,348 KB
testcase_08 AC 2 ms
4,348 KB
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 AC 34 ms
14,664 KB
testcase_13 AC 20 ms
6,052 KB
testcase_14 WA -
testcase_15 AC 27 ms
15,680 KB
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 WA -
testcase_24 AC 245 ms
21,480 KB
testcase_25 AC 213 ms
22,176 KB
testcase_26 AC 210 ms
22,184 KB
testcase_27 AC 205 ms
22,004 KB
testcase_28 AC 83 ms
18,424 KB
testcase_29 AC 228 ms
30,672 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
using ll = long long;
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
#else
#define show(x) true
#endif
struct UnionFind{
	vector<int> par,rank;
	UnionFind(int N){
		par.assign(N,0);
		rank.assign(N,0);
		rep(i,N) par[i]=i;
	}
	int find(int x){
		if(par[x]==x) return x;
		return par[x]=find(par[x]);
	}
	bool same(int x,int y){
		return find(x)==find(y);
	}
	void unite(int x,int y){
		x=find(x),y=find(y);
		if(x==y) return;
		if(rank[x]<rank[y]) swap(x,y);

		//x becomes root
		par[y]=x;
		if(rank[x]==rank[y]) rank[x]++;
	}
};
int bsr(int x){	//4~7 -> 2
	if(x==0) return -1;
	return 31 ^ __builtin_clz(x);
}
struct LCA{
	int N,n;
	vector<int> depth;
	vector<vector<int>> par;

	void dfs(int v,int p,const vector<vector<int>>& G){
		if(p<0) depth[v]=0;
		else depth[v]=depth[p]+1;
		par[v][0]=p;
		for(int u:G[v]){
			if(u!=p) dfs(u,v,G);
		}
	}

	LCA(const vector<vector<int>>& G){
		N = G.size();
		n = bsr(N);
		depth = vector<int>(N,0);
		par = vector<vector<int>>(N,vector<int>(n+1,0));

		dfs(0,-1,G);
		rep1(i,n){
			rep(v,N){
				if(par[v][i-1]==-1){
					par[v][i]=-1;
				}else{
					par[v][i]=par[par[v][i-1]][i-1];
				}
			}
		}
	}

	int lca(int u,int v){
		if(depth[u]<depth[v]){
			swap(u,v);
		}
		int d=depth[u]-depth[v];
		rep(i,n+1){
			if((d>>i)&1) u=par[u][i];
		}
		if(u==v) return u;
		for(int i=n;i>=0;i--){
			if(par[u][i]!=par[v][i]){
				u=par[u][i];
				v=par[v][i];
			}
		}
		return par[v][0];
	}

	int distance(int u,int v){
		return depth[u] + depth[v] - 2*depth[lca(u,v)];
	}
};
int main(){
	int N,M,Q; cin >> N >> M >> Q;
	UnionFind UF(N);
	VV<int> G(N);
	rep(i,M){
		int x,y; cin >> x >> y; x--,y--;
		G[x].pb(y); G[y].pb(x);
		UF.unite(x,y);
	}
	LCA lca(G);
	ll ans = 0;
	V<ll> w(N);
	rep(_,Q){
		int x,y; cin >> x >> y; x--,y--;
		if(UF.same(x,y)){
			ans += lca.distance(x,y);
		}else{
			w[x]++,w[y]++;
		}
	}
	V<ll> wsm(N);
	rep(r,N) if(UF.find(r) == r){
		ll sm = 0;
		function<void(int,int,int)> dfs = [&](int v,int p,int depth){
			sm += w[v] * depth;
			wsm[v] = w[v];
			for(int u: G[v]) if(u != p){
				dfs(u,v,depth+1);
				wsm[v] += wsm[u];
			}
		};
		dfs(r,-1,0);
		ll mn = sm;
		function<void(int,int)> dfs2 = [&](int v,int p){
			chmin(mn,sm);
			for(int u: G[v]) if(u != p){
				sm -= wsm[u] - (wsm[r]-wsm[u]);
				dfs2(u,v);
				sm += wsm[u] - (wsm[r]-wsm[u]);
			}
		};
		dfs2(r,-1);
		ans += mn;
	}
	cout << ans << endl;
}
0