답안 #54902

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
54902 2018-07-05T09:24:30 Z 노영훈(#1508) Pipes (CEOI15_pipes) C++11
100 / 100
4024 ms 9332 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MX=100010, inf=2e9;

int n, m;
vector<pii> G[MX];

int U[MX];

pii par[MX];

int dep[MX];

int sz[MX];

int root[MX];

int rnk[MX];

inline int find(int x){
    return x==U[x] ? x : U[x]=find(U[x]);
}
void unite(int x, int y){
    if(find(x)==find(y)) return;
    x=U[x], y=U[y];
    if(rnk[x]<rnk[y]) swap(x,y);
    if(rnk[x]==rnk[y]) rnk[x]++;
    U[y]=x;
}


void dfs(int v, int p, int d){
    dep[v]=d, root[v]=root[p];
    for(pii &e:G[v]){
        int x=find(e.first);
        if(x==p) continue;
        par[x]={e.second, e.first};
        dfs(x,v,d+1);
    }
}

void merge(int u, int v){
    if(sz[root[find(u)]]<sz[root[find(v)]]) swap(u,v);
    // v(b)를 u(a)밑에 붙인다.
    int a=find(u), b=find(v);
    G[a].push_back({v,u});
    G[b].push_back({u,v});
    sz[root[a]]+=sz[root[b]];
    par[b]={u,v};
    dfs(b, a, dep[a]+1);
}


vector<int> A;
vector<pii> adj;
void lca(int u, int v){
    A.clear(); adj.clear();
    u=find(u), v=find(v);
    while(u!=v){
        if(dep[u]>dep[v]){
            A.push_back(u);
            u=find(par[u].first);
        }
        else{
            A.push_back(v);
            v=find(par[v].first);
        }
    }
    A.push_back(u);
    for(int &v:A) unite(v,u);
    int p=find(u), pdep=dep[u]; pii ppar=par[u];
    for(int &v:A){
        for(pii &e:G[v]){
            int x=find(e.first);
            if(x==p) continue;
            adj.push_back(e);
        }
        // G[v].clear();
    }
    // dep ???
    dep[p]=pdep;
    par[p]=ppar;
    G[p]=adj;
}

void init(){
    for(int i=1; i<=n; i++){
        U[i]=i, par[i]={0,0}, dep[i]=0, sz[i]=1, root[i]=i, rnk[i]=1;
    }
}

void solve(){
    for(int v=1; v<=n; v++){
        if(find(v)!=v) continue;
        if(par[v]==pii(0,0)) continue;
        cout<<par[v].first<<' '<<par[v].second<<'\n';
    }
}

void debug(){
    for(int v=1; v<=n; v++){
        if(find(v)==v){
            cout<<v<<": ";
            for(pii &e:G[v]) cout<<find(e.first)<<' ';
            cout<<'\n';
        }
    }
    cout<<'\n';
}

int main(){
    ios::sync_with_stdio(0); cin.tie(0);
    cin>>n>>m;
    init();
    for(int i=1; i<=m; i++){
        int u, v; cin>>u>>v;
        if(find(u)==find(v)) continue;
        if(root[find(u)]==root[find(v)]){
            lca(u, v);
        }
        else{
            merge(u, v);
        }
        // debug();
    }
    solve();
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 2688 KB Output is correct
2 Correct 4 ms 2688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 3044 KB Output is correct
2 Correct 8 ms 2944 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 95 ms 3000 KB Output is correct
2 Correct 90 ms 2984 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 177 ms 3300 KB Output is correct
2 Correct 178 ms 3372 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 394 ms 4308 KB Output is correct
2 Correct 278 ms 4524 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1655 ms 7304 KB Output is correct
2 Correct 538 ms 7164 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2408 ms 7964 KB Output is correct
2 Correct 962 ms 7672 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3772 ms 9136 KB Output is correct
2 Correct 1107 ms 9084 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4024 ms 9332 KB Output is correct
2 Correct 1340 ms 9080 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3672 ms 8836 KB Output is correct
2 Correct 1726 ms 8824 KB Output is correct