結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
sigma425
|
| 提出日時 | 2019-11-09 10:26:19 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,120 bytes |
| コンパイル時間 | 2,457 ms |
| コンパイル使用メモリ | 209,456 KB |
| 最終ジャッジ日時 | 2025-01-08 03:44:41 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge6 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 14 WA * 12 |
ソースコード
#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;
}
sigma425