CF1242B. 0-1 MST
2024-09-05 21:04:41
题目大意
有一个n个点的完全图,上面有m条边的权值为1,其余为0
求MST
n,m<=10^5
题解
方法一:
维护一个点集,表示当前MST中的点
一开始任意加一个点
对于一个未加入的点,如果和点集中的点的1边数<点集大小,那么必定有0边
所以用堆维护与点集中点有1边的条数的点,每次取出度数最小的
重点:c++的堆的比较函数不太一样
如果一个点的度数=点集大小,答案+1
之后把这个点加进点集(即覆盖其余的点)
方法二:
暴力bfs,用set维护剩余未加入的点
如果用一个点取扩展其余的点,每个点会被0边覆盖一次,每条1边也只会被找到一次
所以时间是O((n+m)log)的
code
方法一
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
using namespace std;
struct type{
int s,x;
friend bool operator < (type a,type b) {return a.s>b.s;}
};
priority_queue<type> heap;
int a[200002][2];
int ls[100001];
int b[100001];
int d[100001];
int bz[100001];
int n,m,i,j,k,l,len,ans;
void New(int x,int y)
{
++len;
a[len][0]=y;
a[len][1]=ls[x];
ls[x]=len;
}
int main()
{
// freopen("b.in","r",stdin);
len=1;
scanf("%d%d",&n,&m);ans=n;
fo(i,1,m)
{
scanf("%d%d",&j,&k);
New(j,k);
New(k,j);
}
fo(i,1,n)
heap.push(type{0,i});
ans=0;
fo(l,0,n-1)
{
if (heap.top().s==l)
++ans;
i=heap.top().x;
bz[i]=1;
heap.pop();
for (j=ls[i]; j; j=a[j][1])
if (!bz[a[j][0]])
{
++d[a[j][0]];
heap.push(type{d[a[j][0]],a[j][0]});
}
while (!heap.empty() && heap.top().s<d[heap.top().x])
heap.pop();
}
printf("%d\n",ans-1);
}
最新文章
- Ubuntu 下安装QT
- 【转】 iOS9.2-iOS9.3.3越狱插件清单
- 【Linux学习】Linux操作技巧
- 在easyui的treeGrid中添加checkbox(jquery)
- qq邮箱邮我组件
- 【C++】array初始化0
- fill 函数
- javascript的一点误解
- EF4 Code First和EF6 Code First链接mysql的方法
- Android接口测试-JUnit入门
- show engines 解释
- prometeus, grafana部署以及监控mysql
- javaweb之验证码验证技术
- Linux磁盘挂载详述
- php接口 接受ios或android端图片; php接收NSData数据
- 【第三十九章】 微服务CICD(1)- gitlab搭建与使用(docker版)
- Linux:提示符PS1个性设置
- 20165301陈潭飞2017-2018-2 20165301 实验三《Java面向对象程序设计》实验报告
- FastReport.Net使用:[37]报表继承
- SharePoint 2013 排错之&;quot;Code blocks are not allowed in this file&;quot;