結果
| 問題 |
No.922 東北きりきざむたん
|
| コンテスト | |
| ユーザー |
milanis48663220
|
| 提出日時 | 2019-11-08 23:19:54 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
RE
|
| 実行時間 | - |
| コード長 | 5,016 bytes |
| コンパイル時間 | 1,594 ms |
| コンパイル使用メモリ | 85,168 KB |
| 実行使用メモリ | 25,668 KB |
| 最終ジャッジ日時 | 2024-09-15 02:27:05 |
| 合計ジャッジ時間 | 5,269 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 RE * 1 |
| other | AC * 1 WA * 25 |
ソースコード
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
struct edge{
int to, cost;
};
vector<int> G[100001];
long dp1[100001];
long dp2[100001];
bool used[100001];
int a[100001], b[100001], cnt[100001];
int u[100001], v[100001];
vector<edge> Ge[100001];
vector<int> et;
int depth[100001];
int idx[100001];
struct UnionFind {
vector<int> data;
UnionFind(int size) : data(size, -1) { }
bool unionSet(int x, int y) {
x = root(x); y = root(y);
if (x != y) {
if (data[y] < data[x]) swap(x, y);
data[x] += data[y]; data[y] = x;
}
return x != y;
}
bool findSet(int x, int y) {
return root(x) == root(y);
}
int root(int x) {
return data[x] < 0 ? x : data[x] = root(data[x]);
}
int size(int x) {
return -data[root(x)];
}
};
template <typename T>
struct segtree{
long n;
T UNIT;
vector<T> dat;
segtree(long n_, T unit){
UNIT = unit;
n = 1;
while(n < n_) n *= 2;
dat = vector<T>(2*n);
for(long i = 0; i < 2*n; i++) dat[i] = UNIT;
}
//これを変更
T calc(T a, T b){
if(depth[a] < depth[b]){
return a;
}else{
return b;
}
}
void insert(long k, T a){
dat[k+n-1] = a;
}
void update_all(){
for(long i = n-2; i >= 0; i--){
dat[i] = calc(dat[i*2+1], dat[i*2+2]);
}
}
//k番目の値(0-indexed)をaに変更
void update(long k, T a){
k += n-1;
dat[k] = a;
while(k > 0){
k = (k-1)/2;
dat[k] = calc(dat[k*2+1], dat[k*2+2]);
}
}
//[a, b)
//区間[a, b]へのクエリに対してはquery(a, b+1, 0, 0, segtree.n)と呼ぶこと
T query(long a, long b, long k, long l, long r){
if(r <= a || b <= l) return UNIT;
if(a <= l && r <= b) return dat[k];
else{
T vl = query(a, b, k*2+1, l, (l+r)/2);
T vr = query(a, b, k*2+2, (l+r)/2, r);
return calc(vl, vr);
}
}
};
typedef long long ll;
int N, M, Q;
long m;
vector<int> buf;
void clear(){
for(int i = 0; i < buf.size(); i++) used[buf[i]] = false;
}
void dfs1(int v){
used[v] = true;
buf.push_back(v);
dp1[v] += cnt[v];
for(int i = 0; i < G[v].size(); i++){
if(!used[G[v][i]]){
dfs1(G[v][i]);
dp1[v] += dp1[G[v][i]];
}
}
}
void dfs2(int v){
used[v] = true;
buf.push_back(v);
dp2[v] += cnt[v];
for(int i = 0; i < G[v].size(); i++){
if(!used[G[v][i]]){
dp2[G[v][i]] = dp2[v]+dp1[v]-dp1[G[v][i]];
dfs2(G[v][i]);
}
}
}
void dfs3(int v, int d){
used[v] = true;
depth[v] = d;
for(long i = 0; i < G[v].size(); i++){
if(!used[G[v][i]]){
et.push_back(G[v][i]);
idx[G[v][i]] = et.size()-1;
dfs3(G[v][i], d+1);
et.push_back(v);
}
}
}
long dist[100001];
void dfs4(long v, long d){
used[v] = true;
dist[v] = d;
for(long i = 0; i < Ge[v].size(); i++){
if(!used[Ge[v][i].to]){
dfs4(Ge[v][i].to, d+Ge[v][i].cost);
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
cin >> N >> M >> Q;
UnionFind uf(N);
for(int i = 0; i < M; i++){
cin >> u[i] >> v[i];
Ge[u[i]].push_back((edge){v[i], 1});
Ge[v[i]].push_back((edge){u[i], 1});
G[u[i]].push_back(v[i]);
G[v[i]].push_back(u[i]);
uf.unionSet(u[i], v[i]);
}
long ans = 0;
int cnt_div = 0;
for(int i = 0; i < Q; i++){
cin >> a[i] >> b[i];
if(!uf.findSet(a[i], b[i])){
cnt[a[i]]++;
cnt[b[i]]++;
}
}
vector<int> ap;
for(int i = 0; i < N; i++){
if(!used[i]){
dfs1(i);
clear();
buf.clear();
dp2[i] = 0;
dfs2(i);
long cnt_min = 1e+15;
int idx = -1;
for(int j = 0; j < buf.size(); j++){
if(cnt_min > (dp1[buf[j]]+dp2[buf[j]])){
idx = buf[j];
cnt_min = (dp1[buf[j]]+dp2[buf[j]]);
}
}
if(idx == -1) continue;
Ge[0].push_back((edge){idx, 0});
Ge[idx].push_back((edge){0, 0});
buf.clear();
}
}
// cout << 'H' << endl;
dfs3(0, 0);
for(int i = 0; i <= N; i++) used[i] = false;
dfs4(0, 0);
depth[N+1] = N+2;
segtree<long> sgt(et.size()+1, N+1);
for(long i = 0; i < et.size(); i++){
sgt.insert(i, et[i]);
}
sgt.update_all();
for(int i = 0; i < Q; i++){
int id[2]; id[0] = idx[a[i]]; id[1] = idx[b[i]];
int p = sgt.query(id[0], id[1], 0, 0, sgt.n);
ans += (dist[a[i]]+dist[b[i]]-dist[p]*2);
}
cout << ans << endl;
}
milanis48663220