답안 #535350

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
535350 2022-03-10T05:08:16 Z 79brue 수도 (JOI20_capital_city) C++14
0 / 100
1087 ms 381068 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

int n, k;
int arr[200002], idx[200002];
vector<int> link[200002];
vector<int> vec[200002];

int in[200002], inCnt, sz[200002];
int top[200002], depth[200002], par[200002], LCADB[200002][20];

void dfs_sz(int x, int p=-1){
    sz[x] = 1;
    for(auto &y: link[x]){
        if(y==p) continue;
        depth[y] = depth[x] + 1;
        par[y] = LCADB[y][0] = x;
        dfs_sz(y, x);
        sz[x] += sz[y];
        if(sz[y] > sz[link[x][0]]) swap(y, link[x][0]);
    }
}

void dfs_hld(int x, int p=-1){
    in[x] = ++inCnt;
    idx[inCnt] = x;
    for(auto y: link[x]){
        if(p==y) continue;
        top[y] = (y==link[x][0]) ? top[x] : y;
        dfs_hld(y, x);
    }
}

int getLCA(int x, int y){
    if(depth[x] < depth[y]) swap(x, y);
    for(int d=0; d<20; d++) if((depth[x] - depth[y]) & (1<<d)) x = LCADB[x][d];
    if(x==y) return x;
    for(int d=19; d>=0; d--) if(LCADB[x][d] != LCADB[y][d]) x = LCADB[x][d], y = LCADB[y][d];
    return par[x];
}

vector<int> graphLink[1000002];
vector<int> revLink[1000002];
bool visited[1000002];
stack<int> stk;
int ans = 1e9;
int cnt;
int sccNum[1000002];
vector<int> sccLink[1000002];
int weight[1000002];
int deg[1000002];

void sccDfs1(int x){
    visited[x] = 1;
    for(auto y: graphLink[x]){
        if(visited[y]) continue;
        sccDfs1(y);
    }
    stk.push(x);
}

void sccDfs2(int x, int t){
    visited[x] = 1;
    sccNum[x] = t;
    for(auto y: revLink[x]){
        if(visited[y]) continue;
        sccDfs2(y, t);
    }
}

void init(int i, int l, int r){
    if(l==r){
        graphLink[i].push_back(4*n+arr[idx[l]]);
        return;
    }
    int m = (l+r)>>1;
    graphLink[i].push_back(i*2);
    graphLink[i].push_back(i*2+1);
    init(i*2, l, m);
    init(i*2+1, m+1, r);
}

void update(int i, int l, int r, int s, int e, int x){
    if(r<s || e<l) return;
    if(s<=l && r<=e){
        graphLink[4*l+x].push_back(i);
        return;
    }
    int m = (l+r)>>1;
    update(i*2, l, m, s, e, x);
    update(i*2+1, m+1, r, s, e, x);
}

int main(){
    scanf("%d %d", &n, &k);
    for(int i=1; i<n; i++){
        int x, y;
        scanf("%d %d", &x, &y);
        link[x].push_back(y);
        link[y].push_back(x);
    }
    for(int i=1; i<=n; i++){
        scanf("%d", &arr[i]);
        vec[arr[i]].push_back(i);
    }

    dfs_sz(1);
    top[1] = 1; dfs_hld(1);
    for(int d=1; d<20; d++) for(int i=1; i<=n; i++) LCADB[i][d] = LCADB[LCADB[i][d-1]][d-1];
    init(1, 1, n);

    for(int i=1; i<=k; i++){
        sort(vec[i].begin(), vec[i].end(), [&](auto x, auto y){
            return in[x] < in[y];
        });
        for(int j=0; j<(int)vec[i].size() - 1; j++){
            int x = vec[i][j];
            int y = vec[i][j+1];
            int z = getLCA(x, y);

            while(top[x] != top[y]){
                if(depth[top[x]] < depth[top[y]]) swap(x, y);
                update(1, 1, n, in[top[x]], in[x], i);
                x = par[top[x]];
            }
            if(depth[x] > depth[y]) swap(x, y);
            update(1, 1, n, in[x], in[y], i);
        }
    }

    for(int i=1; i<=5*n; i++){
        if(!visited[i]) sccDfs1(i);
    }
    memset(visited, 0, sizeof(visited));
    for(int i=1; i<=5*n; i++) for(auto x: graphLink[i]) revLink[x].push_back(i);
    while(!stk.empty()){
        if(!visited[stk.top()]) sccDfs2(stk.top(), stk.top());
        stk.pop();
    }

    for(int i=1; i<=5*n; i++){
        for(auto x: link[i]){
            sccLink[sccNum[x]].push_back(sccNum[i]);
            deg[sccNum[i]]++;
        }
        if(i>4*n) weight[sccNum[i]]++;
    }

    queue<int> que;
    for(int i=1; i<=5*n; i++) if(!deg[i]) que.push(i);

    while(!que.empty()){
        int x = que.front(); que.pop();
        if(weight[x]) ans = min(weight[x]-1, 0);

        for(auto y: sccLink[x]){
            deg[y]--;
            weight[y] += weight[x];
            weight[y] = min(weight[y], 1000000);
            if(!deg[y]) que.push(y);
        }
    }

    printf("%d", ans);
}

Compilation message

capital_city.cpp: In function 'int main()':
capital_city.cpp:122:17: warning: unused variable 'z' [-Wunused-variable]
  122 |             int z = getLCA(x, y);
      |                 ^
capital_city.cpp:98:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   98 |     scanf("%d %d", &n, &k);
      |     ~~~~~^~~~~~~~~~~~~~~~~
capital_city.cpp:101:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  101 |         scanf("%d %d", &x, &y);
      |         ~~~~~^~~~~~~~~~~~~~~~~
capital_city.cpp:106:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  106 |         scanf("%d", &arr[i]);
      |         ~~~~~^~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 36 ms 81100 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 36 ms 81100 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 1087 ms 381068 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 36 ms 81100 KB Output isn't correct
2 Halted 0 ms 0 KB -