【分块答案】【最小生成树】【kruscal】bzoj1196 [HNOI2006]公路修建问题
2024-09-20 02:44:43
二分(分块)枚举 边权上限。用kruscal判可行性。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int u[20001],v[20001],w1[20001],w2[20001],n,m,K,Limit;
int fa[10001],rank[10002];
void init()
{
for(int i=1;i<=n;i++) fa[i]=i;
memset(rank,0,(n+1)*sizeof(int));
}
int findroot(int x)
{
if(x==fa[x]) return x;
int rt=findroot(fa[x]);
fa[x]=rt;
return rt;
}
void Union(const int &U,const int &V)
{
if(rank[U]<rank[V]) fa[U]=V;
else
{
fa[V]=U;
if(rank[U]==rank[V]) ++rank[U];
}
}
bool Kruscal(int x)//仅仅需要接通即可。
{
init(); int cnt=0;
for(int i=1;i<=m;++i) if(w1[i]<=x)
{
int f1=findroot(u[i]),f2=findroot(v[i]);
if(f1!=f2)
{
Union(f1,f2);
++cnt;
if(cnt==n-1) return 1;
}
}
if(cnt<K) return 0;
for(int i=1;i<=m;++i) if(w2[i]<=x)
{
int f1=findroot(u[i]),f2=findroot(v[i]);
if(f1!=f2)
{
Union(f1,f2);
++cnt;
if(cnt==n-1) return 1;
}
}
return cnt==n-1?1:0;
}
int main()
{
scanf("%d%d%d",&n,&K,&m);
for(int i=1;i<=m;++i)
{
scanf("%d%d%d%d",&u[i],&v[i],&w1[i],&w2[i]);
Limit=max(Limit,w1[i]);
}
int sz=sqrt(Limit),last=0;
for(int i=1;last<=Limit;i+=sz)
{
if(Kruscal(i))
for(int j=last+1;j<=i;++j)
if(Kruscal(j))
{
printf("%d\n",j);
return 0;
}
last=i;
}
}
最新文章
- Python标准模块--os
- SSDB图形界面管理工具:phpssdbadmin安装部署
- AngularJS之Filter(二)
- CentOS双网卡绑定bond0
- <;jsp:include page=";"; />;路径
- sublime text 3 license 2016.05
- Python3操作MySQL,查询数据并保存到文件中
- [iOS翻译]《iOS 7 Programming Cookbook》:iOS文件与文件夹管理(上)
- eclipse运行时编码设置
- 【自动化测试】Selenium excel操作
- 如何使用Fiddler调试线上JS代码
- SQl为表添加和删除列
- unity3d 获取相机视口四个角的坐标
- STM8建立IAR工程
- xxe漏洞的学习与利用总结
- iOS之网络请求NSURLSession剖析
- 深入浅出 TCP/IP 协议
- 【hjmmm网络流24题补全计划】
- icomoon:生成字体图标的方法并应用
- pthread_detach
热门文章
- Any gotchas at all with converting from MyISAM to InnoDB?
- D. Equalize the Remainders (set的基本操作)
- Ubuntu14.04 换源 阿里云
- Spring学习-- SpEL表达式
- lhgdialog的传值问题
- netty学习指南
- [bzoj2251][2010Beijing Wc]外星联络——后缀数组+暴力求解
- bzoj 1996 DP
- 时间模块(time/date)
- Linux中实现一个简单的进度条【转】