BZOJ 3060: [Poi2012]Tour de Byteotia 并查集
前 $k$ 个节点形成的结构必定是森林,而 $[k+1,r]$ 之间肯定是都连上,而剩下的一个在 $[1,k],$一个在 $[k+1,r]$ 的节点就能连多少连多少即可.
Code:
#include <bits/stdc++.h>
#define N 1000005
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
struct Edge
{
int u,v;
}e[N<<1];
int p[N];
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
int main()
{
// setIO("input");
int n,m,k,i,j,cnt=0;
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=n;++i) p[i]=i;
for(i=1;i<=m;++i)
{
scanf("%d%d",&e[i].u,&e[i].v);
if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
if(e[i].v<=k)
{
int xx=find(e[i].u),yy=find(e[i].v);
if(xx!=yy)
{
p[xx]=yy;
++cnt;
}
}
else if(e[i].u>k)
{
++cnt;
int xx=find(e[i].u),yy=find(e[i].v);
p[xx]=yy;
}
}
for(i=1;i<=m;++i)
{
if(e[i].u<=k&&e[i].v>k)
{
int xx=find(e[i].u),yy=find(e[i].v);
if(xx!=yy) p[xx]=yy,++cnt;
}
}
printf("%d\n",m-cnt);
return 0;
}

浙公网安备 33010602011771号