背景:
第一道难度暂无评定的题。
第三个通过的。
题目传送门:
https://www.luogu.org/problem/P3535
题意:
n
n
n个点,
m
m
m条边,删掉最少的边的数目,使得编号小于等于
k
k
k的点都不在环上。
思路:
容易想到若边
(
x
,
y
)
(x,y)
(x,y)满足
x
,
y
>
k
x,y>k
x,y>k,则这条边是不用理的,暴力加到并查集中即可。
否则若
(
x
,
y
)
(x,y)
(x,y)有至少一个点的编号小于等于
k
k
k,若这两点在环中,则至少要删掉
1
1
1条边使得它们不连通;否则让它们联通即可。
直接并查集判断是否环即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k,ans=0;
int fa[1000010];
struct node{int x,y;} a[1000010];
int find(int x)
{
return x==fa[x]?x:fa[x]=find(fa[x]);
}
void Union(int x,int y)
{
int t1=find(x),t2=find(y);
if(t1!=t2) fa[t1]=t2;
}
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",&a[i].x,&a[i].y);
if(a[i].x>k&&a[i].y>k)
{
int t1=find(a[i].x),t2=find(a[i].y);
if(t1!=t2) fa[t1]=t2;
}
}
for(int i=1;i<=m;i++)
if(a[i].x<=k||a[i].y<=k)
{
int t1=find(a[i].x),t2=find(a[i].y);
if(t1!=t2) fa[t1]=t2; else ans++;
}
printf("%d",ans);
}