結果
| 問題 |
No.3200 Sinking Islands
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-11 23:05:31 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 1,696 bytes |
| コンパイル時間 | 954 ms |
| コンパイル使用メモリ | 91,824 KB |
| 実行使用メモリ | 10,576 KB |
| 最終ジャッジ日時 | 2025-07-11 23:05:43 |
| 合計ジャッジ時間 | 10,285 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | WA * 20 |
ソースコード
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
using ll = long long;
using P = pair<int, int>;
struct UnionFind{
vector<int> par, siz, rank;
UnionFind(int n) : par(n, -1), siz(n, 1), rank(n, 1) {} //メンバ変数をどのように初期化するかを表す
//根を求めるやつ
int root(int x){
if(par[x]==-1) return x;
else return par[x]=root(par[x]);
}
//xを含むグループとyを含むグループとを併合する
bool unite(int x, int y){
x=root(x); y=root(y);
if(x==y) return false;
if(rank[x]<rank[y]) swap(x, y);
if(rank[x]==rank[y]) rank[x]++;
par[y]=x;
siz[x]+=siz[y];
return true;
}
int size(int x){
return siz[root(x)];
}
};
int main(){
int n, m; cin >> n >> m;
vector<P> bri;
for(int i=0; i<m; i++){
int u, v; cin >> u >> v; u--, v--;
bri.emplace_back(u, v);
}
int q; cin >> q;
vector<int> cant(m), briidx;
for(int i=0; i<q; i++){
int b; cin >> b; b--;
cant[b]++;
briidx.push_back(b);
}
UnionFind uf(n);
for(int i=0; i<m; i++) if(cant[i]==0){
auto [u, v]=bri[i];
uf.unite(u, v);
}
ll allpair=n*(n-1)/2, now=0;
vector<ll> ans(q);
vector<bool> checked(n, false);
for(int i=0; i<n; i++){
int p=uf.root(i);
if(checked[p]) continue;
ll k=uf.size(p);
now+=k*(k-1)/2;
checked[p]=true;
}
//cout << allpair-now << endl;
for(int i=q-1; i>=0; i--){
ans[i]=allpair-now;
auto [u, v]=bri[briidx[i]];
u=uf.root(u), v=uf.root(v);
if(u==v) continue;
ll p=uf.size(u), q=uf.root(v);
now+=p*q;
uf.unite(u, v);
}
for(auto p:ans) cout << p << endl;
return 0;
}