多个连通块,要求没有环,至少删除多少条边?成环的边不要即可。

#include <stdio.h>
int n, m, i, j, k, a, b, f[200050];
int find(int x){
    if(x == f[x]) return x;
    return f[x] = find(f[x]);
}
int main(){
    scanf("%d%d", &n, &m);
    for(i=1; i<=n; i++) f[i] = i;
    for(i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        if(find(a) == find(b)) k++;//成环删边
        else f[f[a]] = f[b];//边留下合并
    }
    printf("%d\n", k);
    return 0;
}

没学并查集也能做:

#include <stdio.h>
#define N 200050
int n, m, i, j, k, a, b, c, s, h[N], v[N];
struct AB{
    int a, b, n;
} d[N*2];
void cun(int a, int b){
    d[++k].a = a, d[k].b = b;
    d[k].n = h[a], h[a] = k;
}
void dfs(int a){
    int b, i;
    if(v[a]) return;
    v[a] = ++c;
    for(i=h[a]; i; i=d[i].n) dfs(d[i].b);
}
int main(){
    scanf("%d%d", &n, &m);
    for(i=1; i<=m; i++){
        scanf("%d%d", &a, &b);
        cun(a, b);
        cun(b, a);
    }
    for(i=1; i<=n; i++){
        if(!v[i]){
            c = 0;
            dfs(i);
            s += c - 1;
        }//每个连通块保留c-1条边
    }
    printf("%d\n", m-s);
    return 0;
}

作者 crxis

发表回复