Description
给定一个n个点m条边的无向图,问最少删掉多少条边能使得编号小于等于k的点都不在环上。
【题目分析】
首先把两个端点都大于k的加入。然后剩下的边贪心的选择。如果两个端点在不同的连通块中,就选择这一条边。类似于Kruskal算法。
【代码】(水题看思路,30行搞定)
#include <cstdio>
#include <cstring>
int f[2000001],a[2000001],b[2000001],n,m,k,tp=0,ans=0;
inline int get(int k)
{if (f[k]!=k) f[k]=get(f[k]); return f[k];}
inline void swap(int &a,int &b)
{int c=a;a=b;b=c;}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=2;i<=n;++i) f[i]=i;
for (int i=1;i<=m;++i)
{
scanf("%d%d",&a[tp+1],&b[tp+1]);
if (a[tp+1]>b[tp+1]) swap(a[tp+1],b[tp+1]);
if (a[tp+1]>k&&b[tp+1]>k)
{
int m1=get(a[tp+1]),m2=get(b[tp+1]);
if (m1!=m2) f[m1]=m2;
}
else tp++;
}
for (int i=1;i<=tp;++i)
{
int m1=get(a[i]),m2=get(b[i]);
if (m1!=m2) f[m1]=m2;
else ans++;
}
printf("%d\n",ans);
}