結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
snow39
|
| 提出日時 | 2019-11-08 23:32:29 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,791 bytes |
| コンパイル時間 | 1,004 ms |
| コンパイル使用メモリ | 99,796 KB |
| 実行使用メモリ | 27,524 KB |
| 最終ジャッジ日時 | 2024-09-15 02:41:26 |
| 合計ジャッジ時間 | 4,859 ms |
|
ジャッジサーバーID (参考情報) |
judge6 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 9 WA * 17 |
ソースコード
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
using namespace std;
typedef long long ll;
const ll MOD=1e9+7;
int N,M,Q;
vector<int> U,V;
vector<int> A,B;
vector<int> g[100010];
ll num[100010];
ll child[100010];
int used[100010];
#define MAX_LOG_V 21
#define MAX_V 100010
int parent[MAX_LOG_V][MAX_V]; //親を2^k回辿って到達する頂点(根を通り過ぎる場合は-1)
int depth[MAX_V]; //根からの深さ
int root;
void dfs(int v,int p,int d){
parent[0][v]=p;
depth[v]=d;
used[v]=root;
for(int i=0;i<g[v].size();i++){
if(g[v][i]!=p) dfs(g[v][i],v,d+1);
}
}
//初期化
void init(int V){
//parent[0]とdepthを初期化する
//dfs(root,-1,0);
//parentを初期化する
for(int k=0;k+1<MAX_LOG_V;k++){
for(int v=0;v<V;v++){
if(parent[k][v]<0) parent[k+1][v]=-1;
else parent[k+1][v]=parent[k][parent[k][v]];
}
}
}
//uとvのLCAを求める
int lca(int u,int v){
//uとvの深さが同じになるまで親を辿る
if(depth[u]>depth[v]) swap(u,v);
for(int k=0;k<MAX_LOG_V;k++){
if((depth[v]-depth[u])>>k&1){
v=parent[k][v];
}
}
if(u==v) return u;
//二分探索でLCAを求める
for(int k=MAX_LOG_V-1;k>=0;k--){
if(parent[k][u]!=parent[k][v]){
u=parent[k][u];
v=parent[k][v];
}
}
return parent[0][u];
}
void setChild(int now,int par){
child[now]=num[now];
for(auto nex:g[now]){
if(par==nex) continue;
setChild(nex,now);
child[now]+=child[nex];
}
}
ll eval(int now,int par){
ll res=0;
for(auto nex:g[now]){
if(nex==par) continue;
ll p=eval(nex,now);
res+=p+child[nex];
}
return res;
}
ll global;
void rfs(int now,int par,ll val){
global=min(global,val);
for(auto nex:g[now]){
if(nex==par) continue;
ll nexVal=val-child[nex]+(child[used[now]]-child[nex]);
rfs(nex,now,nexVal);
}
}
int main(){
cin>>N>>M>>Q;
U.resize(M);
V.resize(M);
rep(i,M) cin>>U[i]>>V[i];
A.resize(Q);
B.resize(Q);
rep(i,Q) cin>>A[i]>>B[i];
rep(i,M){
U[i]--;V[i]--;
g[U[i]].push_back(V[i]);
g[V[i]].push_back(U[i]);
}
rep(i,N) used[i]=-1;
rep(i,N){
if(used[i]!=-1) continue;
root=i;
dfs(i,-1,0);
}
init(N);
ll ans=0;
rep(i,Q){
A[i]--;B[i]--;
if(used[A[i]]==used[B[i]]){
ans+=depth[A[i]]+depth[B[i]]-depth[lca(A[i],B[i])];
}else{
num[A[i]]++;
num[B[i]]++;
}
}
rep(i,N){
if(used[i]!=i) continue;
setChild(i,-1);
global=eval(i,-1);
rfs(i,-1,global);
ans+=global;
}
cout<<ans<<endl;
return 0;
}
snow39