結果
| 問題 | No.3639 Itsukin |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-26 02:38:11 |
| 言語 | C++23(gcc16) (gcc 16.1.0 + boost 1.90.0) |
| 結果 |
AC
|
| 実行時間 | 431 ms / 2,000 ms |
| + 904µs | |
| コード長 | 1,466 bytes |
| 記録 | |
| コンパイル時間 | 2,907 ms |
| コンパイル使用メモリ | 189,792 KB |
| 実行使用メモリ | 14,308 KB |
| 最終ジャッジ日時 | 2026-08-26 02:38:25 |
| 合計ジャッジ時間 | 12,745 ms |
|
ジャッジサーバーID (参考情報) |
judge2_1 / judge1_0 |
(要ログイン)
| サブタスク | 配点 | 結果 |
|---|---|---|
| サンプル | 0 % | AC * 1 |
| 小課題1 | 10 % | AC * 6 |
| 小課題2 | 15 % | AC * 5 |
| 小課題3 | 15 % | AC * 16 |
| 小課題4 | 20 % | AC * 10 |
| 小課題5 | 10 % | AC * 15 |
| 小課題6 | 30 % | AC * 35 |
| 合計 | 100 点 |
ソースコード
#include<iostream>
#include<vector>
#include<tuple>
#include<algorithm>
using namespace std;
using ll = long long;
using tu = tuple<int, 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)];
}
bool same(int u, int v){
return root(u)==root(v);
}
};
int main(void){
int n, m; cin >> n >> m;
vector<tu> edge;
for(int i=0; i<m; i++){
int u, v, w; cin >> u >> v >> w; u--, v--;
edge.emplace_back(w, u, v);
}
sort(begin(edge), end(edge));
int q; cin >> q;
vector<tu> query;
for(int i=0; i<q; i++){
int p, t; cin >> p >> t; t--;
query.emplace_back(p, t, i);
}
sort(begin(query), end(query));
int ei=0;
vector<int> ans(q);
UnionFind uf(n);
for(int i=0; i<q; i++){
auto [e, t, qi]=query[i];
while(ei<m){
auto [l, u, v]=edge[ei];
if(l<=e) uf.unite(u, v);
else break;
ei++;
}
ans[qi]=uf.size(t);
}
for(auto p:ans) cout << p << '\n';
return 0;
}