杭电多校(8) 7522

题面

题目意思

n n n个点, m m m条边,可能有重边,求每次删除一棵最小生成树,直到不连通为止,记录每条边是第几次操作删除的,如果不会被删除则记为 − 1 -1 1,边的权值为给出的边的编号。

题目思路

二分+并查集

如果一条边会被删除,那么这条边可以在 1 − ⌊ m ( n − 1 ) ⌋ 1 - \lfloor\frac{m}{(n-1)}\rfloor 1(n1)m次之内删除,因为每次会删除 n − 1 n-1 n1条边,根据最小生成树的定义,我们一定是选择权值最小的边先进行连接,那么我们就一定会选择前面权值较小的边先进行连边,选择其在哪次操作内被连上,又因为连边具有二段性,前面操作有相连,后面操作无相连,就具有二段性,我们将在那一轮连上,但如果于 ⌊ m ( n − 1 ) ⌋ \lfloor\frac{m}{(n-1)}\rfloor (n1)m,那肯定是剩下来的边,不会连接,标记一下,最后对每一条边判断一下在哪一次操作被选上,并且那次操作删除了 n − 1 n-1 n1条边

感悟

二分拓展比较巧妙,利用第几次来快速判断是否被删除。

#include <bits/stdc++.h>

using namespace std;

const int N = 101000;

vector<int> fa[N];
int n, m;

int find(int x, int y){
    if(x != fa[x][y]){
        fa[x][y] = find(fa[x][y], y);
    }
    return fa[x][y];
}

void merge(int u, int v, int c){
    fa[find(u, c)][c] = find(v, c);
}

void solve(){

    cin >> n >> m;
    for(int i = 1; i <= n; i ++) fa[i].clear();
    int c = m / (n - 1);
    for(int i = 1; i <= n; i ++){
        for(int j = 0; j < c; j ++) fa[i].push_back(i);
    }
    
    vector<int> ans(m + 1), cnt(m + 1);

    for(int i = 1; i <= m; i ++){
        int u, v;
        cin >> u >> v;
        int l = 0, r = c; 
        while(l < r){
            int mid = l + r >> 1;
            if(find(fa[u][mid], mid) != find(fa[v][mid], mid)) r = mid;
            else l = mid + 1;
        }
        //cout << r << "\n";
        if(r < c){
            merge(u, v, r);
        }
        cnt[r] ++;
        ans[i] = r;
    }

    for(int i = 1; i <= m; i ++){
        if(ans[i] == c || cnt[ans[i]] != n - 1) cout << "-1";
        else cout << ans[i] + 1;
        cout << " \n"[i == m];
    }

}

int main(){

    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    int _ = 1;
    cin >> _;

    while(_ --){
        solve();
    }

    return 0;
}

/*
*/
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值