답안 #910911

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
910911 2024-01-18T09:17:41 Z asdasdqwer Pipes (CEOI15_pipes) C++14
100 / 100
790 ms 14732 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;
    }

    int a,b;

    for (int i=0;i<m;i++) {
        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;
    }

    int steps;
    for (int i=0;i<n;i++) {
        if (p2[i] == i) continue;
        a=i, b=get2(i);
        r2[a]++;
        r2[b]++;
        if (r1[a]<r1[b])swap(a,b);
        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 6744 KB Output is correct
2 Correct 2 ms 6748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 5 ms 6748 KB Output is correct
2 Correct 5 ms 6900 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 68 ms 6744 KB Output is correct
2 Correct 72 ms 6748 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 118 ms 7004 KB Output is correct
2 Correct 136 ms 7100 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 197 ms 7764 KB Output is correct
2 Correct 171 ms 9852 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 258 ms 13376 KB Output is correct
2 Correct 240 ms 13392 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 380 ms 13648 KB Output is correct
2 Correct 400 ms 14000 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 584 ms 14520 KB Output is correct
2 Correct 485 ms 14500 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 641 ms 14524 KB Output is correct
2 Correct 619 ms 14676 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 779 ms 14320 KB Output is correct
2 Correct 790 ms 14732 KB Output is correct