题意:

给你一幅图,然后有几个特殊点 和不特殊点,给你一些已经连了的边,在保证特殊点不能连的前提下,问最多还能添几条边,双向边

思路:
简单题,就是一个特殊点就是一个集合,然后搜一下,最后把还有没连的点连到集合元素最多的上去,然后把所有边都算出来,减去已经连的边就好了
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int N=1e3+10;
const int M=1e5+10; struct asd{
int to;
int next;
};
asd q[M*2];
int head[M*2],tol,num; bool spe[N];
int pp[N];
bool vis[N]; void add(int u,int v)
{
q[tol].to=v;
q[tol].next=head[u];
head[u]=tol++;
} void dfs(int u,int pre)
{
for(int i=head[u];i!=-1;i=q[i].next)
{
int to=q[i].to;
if(vis[to]) continue;
vis[to]=1;
pp[pre]++;
num--;
dfs(to,pre);
}
} int main()
{
int x;
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
memset(spe,0,sizeof(spe));
memset(pp,0,sizeof(pp));
num=n-k; for(int i=1;i<=k;i++)
{
scanf("%d",&x);
spe[x]=1;
pp[x]=1;
} memset(head,-1,sizeof(head));
tol=0;
int u,v;
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
} memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
{
if(spe[i])
{
vis[i]=1;
dfs(i,i);
}
} int mm=-1,kk;
for(int i=1;i<=n;i++)
{
if(mm<pp[i]&&pp[i])
{
kk=i;
mm=pp[i];
}
}
pp[kk]+=num; int ans=0;
for(int i=1;i<=n;i++)
if(spe[i])
ans+=(pp[i]-1)*pp[i]/2;
printf("%d\n",ans-m); return 0;
}

最新文章

  1. C和指针 第十六章 标准函数库 本地跳转setjmp.h
  2. asp.net mvc 中 一种简单的 URL 重写
  3. java抽象-老师的生日-逻辑思维-有趣的面试题-遁地龙卷风
  4. js观察者模式学习
  5. 转:python webdriver API 之操作测试对象
  6. CronTrigger:Corn表达式
  7. &lt;转&gt;Linux环境进程间通信(二): 信号(下)
  8. c#打开指定设备程序以及网址
  9. 第一个Android crackme(2016-05)
  10. UIView的属性
  11. 关于Android attrs 自定义属性的说明
  12. tornada模板学习笔记
  13. 【数据库】MySQL的左连接、右连接和全连接的实现
  14. oracle数据入库出现空格问题
  15. memcpy的函数
  16. Python version 2.7, which was not found in the registry
  17. vue-scroller记录滚动位置
  18. exchange 2010 的两个错误
  19. Linux系统中用stat命令查看文件的三个时间属性
  20. 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证

热门文章

  1. RestTemplate请求
  2. Html5的placeholder属性(IE兼容)
  3. hdu 1413 文件系统
  4. bootstrap-table 行内编辑
  5. 九度OJ 1134:密码翻译 (翻译)
  6. cpio
  7. java中Integer在JDK1.6和JDK1.7中的区别
  8. SpringBoot-(6)-日志SLF4j
  9. llmp_install.zip
  10. Java其实不支持垃圾回收