답안 #313883

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
313883 2020-10-17T08:33:09 Z georgerapeanu 조이터에서 친구를 만드는건 재밌어 (JOI20_joitter2) C++11
0 / 100
12 ms 14336 KB
#include <cstdio>
#include <set>
#include <algorithm>

using namespace std;

const int NMAX = 1e5;

int n,m;

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);
        if(out[find_root(it)].count(x)){
            out[find_root(it)].erase(x);
            out[find_root(it)].insert(y);
        }
    }

    for(auto it:out[x]){
        if(nodes[y].count(it)){
            continue;
        }
        out[y].insert(it);
    }
    
    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;
}

void afis(){
    printf("\n");
    for(int i = 1;i <= n;i++)printf("%d ",find_root(i));printf("\n");
    for(int i = 1;i <= n;i++){
        if(find_root(i) == i){
            printf("root %d\n",i);
            for(auto it:nodes[i])printf("%d ",it);printf("\n");
            for(auto it:in[i])printf("%d ",it);printf("\n");
            for(auto it:out[i])printf("%d ",it);printf("\n");
        }
    }
    printf("\n");
}

int main(){

    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;
}

Compilation message

joitter2.cpp: In function 'void afis()':
joitter2.cpp:108:5: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  108 |     for(int i = 1;i <= n;i++)printf("%d ",find_root(i));printf("\n");
      |     ^~~
joitter2.cpp:108:57: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  108 |     for(int i = 1;i <= n;i++)printf("%d ",find_root(i));printf("\n");
      |                                                         ^~~~~~
joitter2.cpp:112:13: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  112 |             for(auto it:nodes[i])printf("%d ",it);printf("\n");
      |             ^~~
joitter2.cpp:112:51: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  112 |             for(auto it:nodes[i])printf("%d ",it);printf("\n");
      |                                                   ^~~~~~
joitter2.cpp:113:13: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  113 |             for(auto it:in[i])printf("%d ",it);printf("\n");
      |             ^~~
joitter2.cpp:113:48: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  113 |             for(auto it:in[i])printf("%d ",it);printf("\n");
      |                                                ^~~~~~
joitter2.cpp:114:13: warning: this 'for' clause does not guard... [-Wmisleading-indentation]
  114 |             for(auto it:out[i])printf("%d ",it);printf("\n");
      |             ^~~
joitter2.cpp:114:49: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
  114 |             for(auto it:out[i])printf("%d ",it);printf("\n");
      |                                                 ^~~~~~
joitter2.cpp: In function 'int main()':
joitter2.cpp:122:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  122 |     scanf("%d %d",&n,&m);
      |     ~~~~~^~~~~~~~~~~~~~~
joitter2.cpp:132:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  132 |         scanf("%d %d",&x,&y);
      |         ~~~~~^~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 14336 KB Output is correct
2 Correct 10 ms 14336 KB Output is correct
3 Incorrect 12 ms 14336 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 14336 KB Output is correct
2 Correct 10 ms 14336 KB Output is correct
3 Incorrect 12 ms 14336 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 10 ms 14336 KB Output is correct
2 Correct 10 ms 14336 KB Output is correct
3 Incorrect 12 ms 14336 KB Output isn't correct
4 Halted 0 ms 0 KB -