Codeforces Round #385 (Div. 2) C

本文介绍了一种基于图论的算法实现思路,通过寻找联通块来解决特定问题,并给出了详细的实现步骤及C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路如下:

先找联通块

没有特殊点的联通块加起来与在有特殊点中点最多的联通块 这样最多有c2n 即n*(n-1)/2;

剩下的特殊联通块自己加边

代码如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=1005;
vector<int>group[maxn];
int f[maxn],c[maxn];
int Find(int x)
{
	if(f[x]==x)
		return x;
	return f[x]=Find(f[x]);
}
void unite(int u,int v)
{
	int xx=Find(u);
	int yy=Find(v);
	if(xx!=yy) f[xx]=yy;
}
int main()
{
	int n,m,k,u,v; 
	scanf("%d %d %d",&n,&m,&k);
	for(int i=0;i<k;i++)
		scanf("%d",&c[i]);
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int i=0;i<m;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		unite(u,v);
	} 
	int sum1=0,sum=0,ma=0;
	for(int i=0;i<maxn;i++)
		group[i].clear();
	for(int i=1;i<=n;i++)
		group[Find(i)].push_back(i);
	for(int i=0;i<k;i++)
	{
		int temp=Find(c[i]);
		int num=group[temp].size();
		ma=max(num,ma);
		sum1+=num; sum+=(num*(num-1))/2;
	}
	sum1=n-sum1;
	sum1+=ma;
	sum+=(sum1*(sum1-1))/2;
	sum-=(ma*(ma-1))/2;
	sum-=m;
	printf("%d\n",sum);		
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值