小y的旅行

小y的考试

https://ac.nowcoder.com/acm/contest/7780/A

小y的旅行:

题目要你去除最少的边使得小于k的点里面没有环。不难想到用并查集来写,如果x与y本来在一个没有环的连通块内,如果再在这个连通块内加入一条边,那么一定会构成环,所以并查集判断一下是不是在同一个连通块内就行了。首先把两个点都大于k的边给合并,这个并不影响结果,然后判断里面有小于k的点的合并,如果之前已经在一个连通块内,则不需要加入这条边:即删除这条边,判断一下就是删除最少的边了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline ll read(){
    ll s=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9'){
        s=(s<<1)+(s<<3)+(c^48);c=getchar();
    }
    return f*s;
}
const int N=2555555;
int b[N];
struct f{
    int x,y;
}a[N];
int find(int x){
    if(b[x]!=x)b[x]=find(b[x]);
    return b[x];
}
int main(){
    int n=read(),m=read(),k=read(),ans=0;
    for(int i=1;i<=n;i++)b[i]=i;
    for(int i=1;i<=m;i++){
        a[i].x=read(),a[i].y=read();
        if(a[i].x>k&&a[i].y>k&&find(a[i].x)!=find(a[i].y)){
            b[find(a[i].x)]=find(a[i].y);
        }
    }
    for(int i=1;i<=m;i++){
        int x=a[i].x,y=a[i].y;
        if(x<=k||y<=k){            
            if(find(x)==find(y)){
                ans++;
            }
            else{
                b[find(x)]=find(y);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
全部评论
大佬,带带我
点赞 回复 分享
发布于 2020-10-05 18:55

相关推荐

11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务