zoukankan      html  css  js  c++  java
  • 【[POI2012]TOU-Tour de Byteotia】

    【[POI2012]TOU-Tour de Byteotia】

    洛谷P3535

    https://www.luogu.org/problemnew/show/P3535

    JDOJ 2193旅游景点(同类题目)

    https://neooj.com/oldoj/problem.php?id=2193

    知识点:并查集判环

    ps:首先声明一下,这题我只得了20分,但是检查了好多遍代码发现没有问题,看了大佬的题解发现他也得了20分,那就是洛谷数据点有问题了(数据范围啥的都没给还想过?)

    所以大家不要纠结分数,把这个东西弄好了才是最重要的。

    并查集有连通性,其很重要的一个用处就是判环,这个判环用法不仅在一些并查集题中很常见,并且在kruskal算法做MST的时候也是必会用法。

    其原理很简单,如果一个点的父亲节点和另一个点的父亲节点是相同的,那么就可以判定出现了一个环。

    然后针对于本题,正解思路如下:

    不难想到,如果两个点都>k的话,这个边就没有可能被删除。 所以我们只需要先把x,y都>k的边放进并查集,然后再枚举其他<=k的边,如果发现x,y根节点相同,那就累加ans,如果没有的话就不需要删除,加到并查集里。

    TALK LESS , LET ME SHOW YOU

    #include<cstdio>
    #define N 100010
    using namespace std;
    int fa[N],x[N<<1],y[N<<1];
    int n,m,k,ans;
    int find(int x)
    {
        if(fa[x]==x)return x;
        return fa[x]=find(fa[x]);
    }
    void unionn(int x,int y)
    {
        int fx=find(x);
        int fy=find(y);
        if(fx!=fy)
            fa[fx]=fy;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x[i],&y[i]);
            if(x[i]>k && y[i]>k)
                unionn(x[i],y[i]);
        }
        for(int i=1;i<=m;i++)
        {
            if(x[i]<=k || y[i]<=k)
            {
                if(find(x[i])==find(y[i]))
                    ans++;
                else
                    unionn(x[i],y[i]);
            }
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    对象,类,封装,继承,多态是什么
    面向对象和非面向对象程序的区别是什么?
    什么是OOA,OOP
    git stash git tag
    从一个远程仓库同步向另一个远程仓库同步代码
    VScode 配置rust开发环境
    IAR ICCARM V8.32.3在Windows Server端进行Ollydbg破解
    阅读笔记
    FP32转FP16能否加速libtorch调用
    阅读笔记-Chained-Tracker
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11163180.html
Copyright © 2011-2022 走看看