# | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 |
---|---|---|---|---|---|---|---|
313880 | georgerapeanu | Making Friends on Joitter is Fun (JOI20_joitter2) | C++11 | 10 ms | 14496 KiB |
이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <cstdio>
#include <set>
#include <algorithm>
using namespace std;
const int NMAX = 1e5;
int father[NMAX + 5];
set<int> in[NMAX + 5];
set<int> out[NMAX + 5];
set<int> nodes[NMAX + 5];
int find_root(int nod){
if(father[nod] == 0){
return nod;
}
return father[nod] = find_root(father[nod]);
}
int unite(int x,int y){
x = find_root(x);
y = find_root(y);
if(x == y){
return false;
}
if(nodes[x].size() + in[x].size() + out[x].size() > nodes[y].size() + in[y].size() + out[y].size()){
swap(x,y);
}
if((out[x].count(y) && out[y].count(x)) == 0){
return 0;
}
long long delta = 0;
delta -= 1LL * nodes[x].size() * in[x].size();
delta -= 1LL * nodes[x].size() * nodes[x].size();
delta -= 1LL * nodes[y].size() * in[y].size();
delta -= 1LL * nodes[y].size() * nodes[y].size();
father[x] = y;
for(auto it:nodes[x]){
nodes[y].insert(it);
if(in[y].count(it)){
in[y].erase(it);
}
if(out[y].count(it)){
out[y].erase(it);
}
}
for(auto it:in[x]){
if(nodes[y].count(it)){
continue;
}
in[y].insert(it);
}
for(auto it:out[x]){
if(nodes[y].count(it)){
continue;
}
out[y].insert(it);
if(out[find_root(it)].count(y)){
out[find_root(it)].erase(y);
out[find_root(it)].insert(x);
}
}
delta += 1LL * nodes[y].size() * in[y].size();
delta += 1LL * nodes[y].size() * nodes[y].size();
for(auto it:out[x]){
delta += unite(x,it);
}
return delta;
}
int add_edge(int x,int y){
if(find_root(x) == find_root(y)){
return 0;
}
long long delta = 0;
delta -= 1LL * nodes[find_root(y)].size() * in[find_root(y)].size();
delta -= 1LL * nodes[find_root(y)].size() * nodes[find_root(y)].size();
out[find_root(x)].insert(find_root(y));
in[find_root(y)].insert(x);
delta += 1LL * nodes[find_root(y)].size() * in[find_root(y)].size();
delta += 1LL * nodes[find_root(y)].size() * nodes[find_root(y)].size();
delta += unite(x,y);
return delta;
}
int main(){
int n,m;
scanf("%d %d",&n,&m);
for(int i = 1;i <= n;i++){
nodes[i].insert(i);
}
long long ans = 0;
for(int i = 1;i <= m;i++){
int x,y;
scanf("%d %d",&x,&y);
ans += add_edge(x,y);
printf("%lld\n",ans);
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |