图论(连通性)

AT_abc399_c [ABC399C] Make it Forest

题目描述

给定一个由 N 个顶点和 M 条边构成的简单无向图,顶点编号为 1N。第 i 条边连接顶点 ui 和顶点 vi
若要将该图变为森林,至少需要删除多少条边?

森林的定义:简单无向图 F 是森林,当且仅当 F 不包含任何环。

输入格式

输入通过标准输入给出,格式如下:

N M
u1 v1
u2 v2

uM vM

输出格式

输出答案。

输入输出样例 #1

输入 #1

4 4
1 2
1 3
2 4
3 4

输出 #1

1

输入输出样例 #2

输入 #2

5 0

输出 #2

0

输入输出样例 #3

输入 #3

10 10
7 9
4 6
6 10
2 5
5 6
5 9
6 8
4 8
1 5
1 4

输出 #3

2

说明/提示

约束条件

  • 1N2×105
  • 0Mmin(N(N1)2,2×105)
  • 1ui<viN
  • 输入的图是简单无向图(无自环和重边)
  • 所有输入值均为整数

样例解释 1

例如,删除第 1 条边后,该图将变为森林。

翻译由 DeepSeek R1 完成
这道题本质上是要求一个无向图中有几个环,这道题可以用并查集做,如果两条边的的端点的父节点是一样的,说明如果加上这条边就会形成个环,所以不能要这条边
![](https://img2024.cnblogs.com/blog/3599636/202503/3599636-20250331211151574-
175543493.png)

#include<iostream>
#include<vector>
using namespace std;
const int N=2e5+5;
vector<int>v[N];
int vis[N];
void dfs(int x){
    vis[x]=1;
    for(auto y:v[x]){
        if(!vis[y]){
            dfs(y);
        }
    }
}
int ans=0;
int f[N];
int find(int x){
    return x==f[x]?x:f[x]=find(f[x]);
}
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)f[i]=i;
    while(m--){
        int a,b;
        cin>>a>>b;
        int rootx=find(a);
        int rooty=find(b);
        if(rootx==rooty){
            ans++;
            continue;
        }
        f[rootx]=rooty;
    }
    cout<<ans;
    return 0;
}
posted @ 2025-03-31 21:12  郭轩均  阅读(17)  评论(0)    收藏  举报
相关博文:
阅读排行:
· 突发,CSDN 崩了!程序员们开始慌了?
· 完成微博外链备案,微博中直接可以打开园子的链接
· C# WinForms 实现打印监听组件
· C#实现欧姆龙 HostLink 通讯协议库
· 一个基于 .NET 开源、模块化 AI 图像生成 Web 用户界面
点击右上角即可分享
微信分享提示