总之就是 | 洛谷 P3535 TOU-Tour de Byteotia

TOU-Tour de Byteotia

这是一道相对裸的并查集。

因为洛谷题面本身就很简短,在这里就不再做题意简述,下面直接来讲做法。

思路简述

题目让我们求至少删掉多少条边能使得编号小于等于 \(k\) 的点都不在环上,而在并查集中删除并不好操作,于是我们考虑转化。

因为题目只是要求回答个数而非方案,所以我们可以把删点操作转化为计数,具体实现如下。

考虑到最初那个连通块在删去所有边之后,剩下的必然只有编号 \(x\) 满足大约 \(k\) 的点,于是我们在最初建图的时候可以先只把满足要求的点并在一起。

那么剩下的必然都是编号小于等于 \(k\) 的点,考虑如何选择能让题面中所述的删去点的次数更少。

在最坏的情况下,我们把每个点都删除一次。如果我们能利用题目中所给出的边把剩下的点并在一起,就能减少我们的删除操作次数从而减小答案。

Code

实际上面所述的内容用并查集实现很简单,于是下面的代码部分不做过多解释。

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <string.h>
#define Heriko return
#define Deltana 0
#define Romanno 1
#define S signed
#define LL long long
#define R register
#define I inline
#define CI const int
#define mst(a, b) memset(a, b, sizeof(a))
#define ON std::ios::sync_with_stdio(false);cin.tie(0)
using namespace std;

template<typename J>
I void fr(J &x)
{
    short f(1);
    char c=getchar();
    x=0;
    while(c<'0' or c>'9')
    {
        if(c=='-') f=-1;
        c=getchar();
    }
    while (c>='0' and c<='9') 
    {
        x=(x<<3)+(x<<1)+c-'0';
        c=getchar();
    }
    x*=f;
}

template<typename J>
I void fw(J x,bool k)
{
    if(x<0) putchar('-'),x=-x;
    static short stak[35];
    short top(0);
    do
    {
        stak[top++]=x%10;
        x/=10;
    }
    while(x);
    while(top) putchar(stak[--top]+'0');
    if(k) putchar('\n');
    else putchar(' ');
}

CI MXX=8e5+5;

int n,m,k,f[MXX],ans;

struct line
{
    int x,y;
}

r[MXX];

I int Find(const int &x)
{
    if(x!=f[x]) f[x]=Find(f[x]);
    Heriko f[x];
}

S main()
{
    fr(n),fr(m),fr(k);
    for(R int i(1);i<=n;++i) f[i]=i;
    for(R int i(1);i<=m;++i) fr(r[i].x),fr(r[i].y);
    for(R int i(1);i<=m;++i) if(r[i].x>k and r[i].y>k) f[Find(r[i].x)]=Find(r[i].y);
    for(R int i(1);i<=m;++i)
    {
        int fx=Find(r[i].x),fy=Find(r[i].y);
        if(r[i].x<=k or r[i].y<=k)
        {
            if(fx!=fy) f[fx]=fy;
            else ++ans;
        }
    }
    fw(ans,1);
    Heriko Deltana;
}

希望大家能有所收获。

审核的管理员辛苦了!

上一篇:牛客SQL22统计各个部门的工资记录数


下一篇:linux常用命令