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; 
}

  

posted @ 2019-09-11 19:22  EM-LGH  阅读(155)  评论(0编辑  收藏  举报