답안 #910910

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
910910 2024-01-18T09:15:45 Z asdasdqwer Pipes (CEOI15_pipes) C++14
100 / 100
766 ms 14676 KB
// #pragma GCC optimize("Os")

#include <bits/stdc++.h>
using namespace std;

#define MAXN 100000
int p1[MAXN], r1[MAXN], p2[MAXN], r2[MAXN];
int lft[MAXN][18];
vector<int> g[MAXN];

int get1(int i) {
    if (p1[i]!=i && p1[i]!=p1[p1[i]]) p1[i]=get1(p1[i]);
    return p1[i];
}

inline bool unite1(int a,int b) {
    a=get1(a),b=get1(b);
    if (a==b)return false;
    if (r1[a]<r1[b])swap(a,b);
    p1[b]=a;
    if (r1[a]==r1[b])r1[a]++;
    return true;
}

int get2(int i) {
    if (p2[i]!=i && p2[i]!=p2[p2[i]]) p2[i]=get2(p2[i]);
    return p2[i];
}

inline bool unite2(int a,int b) {
    a=get2(a),b=get2(b);
    if (a==b)return false;
    if (r2[a]<r2[b])swap(a,b);
    p2[b]=a;
    if (r2[a]==r2[b])r2[a]++;
    return true;
}

bitset<100000> vis;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int n,m;cin>>n>>m;

    for (int i=0;i<n;i++) {
        p1[i]=i;
        p2[i]=i;
    }

    for (int i=0;i<m;i++) {
        int a,b;cin>>a>>b;a--;b--;
        if (unite1(a,b)) {
            g[a].push_back(b);
            g[b].push_back(a);
        }

        else {
            unite2(a,b);
        }
    }

    for (int i=0;i<n;i++) {
        r1[i]=0;p1[i]=-1;
    }

    // r1.assign(n,0);
    // p1.assign(n,-1);

    for (int i=0;i<n;i++) {
        for (int j=0;j<18;j++) {
            lft[i][j]=-1;
        }
    }
    // lft.assign(n, vector<int>(18,-1));

    for (int i=0;i<n;i++) {
        if (vis[i]) continue;
        int pt=0;
        p1[pt]=i;
        vis[i]=true;
        while (pt != -1) {
            int r=p1[pt--];
            for (int x:g[r]) {
                if (!vis[x]) {
                    vis[x]=true;
                    lft[x][0]=r;
                    r1[x]=r1[r]+1;
                    p1[++pt]=x;
                }
            }
        }
    }

    for (int j=1;j<18;j++) {
        for (int i=0;i<n;i++) {
            lft[i][j]=lft[i][j-1];
            if (lft[i][j] != -1) {
                lft[i][j]=lft[lft[i][j]][j-1];
            }
        }
    }

    for (int i=0;i<n;i++) {
        r2[i]=0;
    }


    for (int i=0;i<n;i++) {
        if (p2[i] == i) continue;
        int a=i, b=get2(i);
        r2[a]++;
        r2[b]++;
        if (r1[a]<r1[b])swap(a,b);
        int steps=r1[a]-r1[b];

        for (int j=0;j<18;j++) {
            if ((steps & (1<<j))) {
                a=lft[a][j];
            }
        }
        
        if (a==b) {
            r2[a]-=2;
            continue;
        }

        for (int j=17;j>-1;--j) {
            if (lft[a][j] != lft[b][j]) {
                a=lft[a][j];
                b=lft[b][j];
            }
        }

        r2[lft[a][0]] -= 2;
    }

    // for (int i=0;i<n;i++) {
    //     lft[i]={lft[i][0]};
    // }

    for (int i=0;i<n;i++) vis[i]=0;

    for (int i=0;i<n;i++) {
        p1[i]=-1;
    }

    for (int i=0;i<n;i++) {
        if (vis[i])continue;
        int pt=0;
        vis[i]=true;
        p1[0]=i;
        while (pt != -1) {
            int r=p1[pt];

            if (g[r].size()==0) {
                if (lft[r][0] != -1) {
                    r2[lft[r][0]] += r2[r];
                }
                pt--;
                continue;
            }

            for (int x:g[r]) {
                if (!vis[x]) {
                    p1[++pt]=x;
                    vis[x]=true;
                }
            }

            g[r].clear();
        }
    }

    for (int i=0;i<n;i++) {
        if (r2[i]==0 && lft[i][0] != -1) {
            cout<<i+1<<" "<<lft[i][0]+1<<"\n";
        }
    }

    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 6756 KB Output is correct
2 Correct 2 ms 6748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 6744 KB Output is correct
2 Correct 4 ms 6748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 69 ms 6748 KB Output is correct
2 Correct 66 ms 6744 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 123 ms 7000 KB Output is correct
2 Correct 164 ms 7004 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 236 ms 7612 KB Output is correct
2 Correct 181 ms 9680 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 248 ms 13136 KB Output is correct
2 Correct 229 ms 13384 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 397 ms 13780 KB Output is correct
2 Correct 396 ms 13744 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 513 ms 14420 KB Output is correct
2 Correct 543 ms 14536 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 631 ms 14676 KB Output is correct
2 Correct 648 ms 14556 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 766 ms 14164 KB Output is correct
2 Correct 731 ms 14516 KB Output is correct