이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define int long long
bool f(vector<int> S){
for(int x:S)if(x==1) return false;
return true;
}
struct Unionfind{
vector<int> par, siz;
//初期化
Unionfind(int n) : par(n,-1) , siz(n,1) {}
int root(int x) {
if(par[x] == -1) return x;
else return par[x] = root(par[x]);
}
bool issame(int x,int y) {
return root(x) == root(y);
}
bool unite(int x, int y){
x = root(x); y = root(y);
if(x == y) return false;
if(siz[x] < siz[y]) swap(x,y);
par[y] = x;
siz[x] += siz[y];
return true;
}
int size(int x) {
return siz[root(x)];
}
};
signed main(){
int N,M,Q;
cin>>N>>M;
vector<vector<int>> G(N);
unordered_map<int,int> m;
map<int,multiset<int>> s;
map<int,pair<int,int>> ed;
map<int,int> edc;
for(int i=0;i<M;i++){
int a,b,c;
cin>>a>>b>>c;
a--;
b--;
ed[i] = {a,b};
edc[i] = c;
m[a*N+b] = max(c,m[a*N+b]);
m[b*N+a] = max(c,m[a*N+b]);
s[a*N+b].insert(c);
s[b*N+a].insert(c);
G[a].push_back(b);
G[b].push_back(a);
}
cin>>Q;
vector<int> T(Q),A(Q),B(Q);
for(int i=0;i<Q;i++){
cin>>T[i]>>A[i]>>B[i];
A[i]--;
}
if(f(T)){
Unionfind uf(N);
vector<pair<int,int>> S(Q);
for(int i=0;i<Q;i++) S[i] = {B[i],A[i]};
map<int,int> ans;
sort(S.rbegin(),S.rend());
vector<tuple<int,int,int>> C = {};
for(int i=0;i<N;i++)for(int j:G[i]){
C.push_back({m[i*N+j],i,j});
}
sort(C.rbegin(),C.rend());
int ind = 0;
for(int i=0;i<Q;i++){
while(ind != 2*(int)(m.size())){
int a,b,c;
tie(a,b,c) = C[ind];
if(a < S[i].first) break;
uf.unite(b,c);
ind++;
}
ans[S[i].first*N+S[i].second] = uf.size(S[i].second);
}
for(int i=0;i<Q;i++) cout<<ans[B[i]*N+A[i]]<<endl;
return 0;
}
if(max({N,M,Q}) <= 10000){
for(int i=0;i<Q;i++){
if(T[i] == 1){
int a,b;
tie(a,b) = ed[A[i]];
s[a*N+b].erase(s[a*N+b].find(edc[A[i]]));
s[a*N+b].insert(B[i]);
swap(a,b);
s[a*N+b].erase(s[a*N+b].find(edc[A[i]]));
s[a*N+b].insert(B[i]);
edc[A[i]] = B[i];
continue;
}
queue<int> q;
q.push(A[i]);
vector<bool> seen(N,false);
seen[A[i]] = true;
while(!q.empty()){
int pos = q.front();
q.pop();
for(int x:G[pos]){
if(seen[x] || *s[pos*N+x].rbegin() < B[i]) continue;
seen[x] = true;
q.push(x);
}
}
int count = 0;
for(int i=0;i<N;i++) count += seen[i];
cout<<count<<endl;
}
return 0;
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |