二分(分块)枚举 边权上限。用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;
}
}

最新文章

  1. Python标准模块--os
  2. SSDB图形界面管理工具:phpssdbadmin安装部署
  3. AngularJS之Filter(二)
  4. CentOS双网卡绑定bond0
  5. &lt;jsp:include page=&quot;&quot; /&gt;路径
  6. sublime text 3 license 2016.05
  7. Python3操作MySQL,查询数据并保存到文件中
  8. [iOS翻译]《iOS 7 Programming Cookbook》:iOS文件与文件夹管理(上)
  9. eclipse运行时编码设置
  10. 【自动化测试】Selenium excel操作
  11. 如何使用Fiddler调试线上JS代码
  12. SQl为表添加和删除列
  13. unity3d 获取相机视口四个角的坐标
  14. STM8建立IAR工程
  15. xxe漏洞的学习与利用总结
  16. iOS之网络请求NSURLSession剖析
  17. 深入浅出 TCP/IP 协议
  18. 【hjmmm网络流24题补全计划】
  19. icomoon:生成字体图标的方法并应用
  20. pthread_detach

热门文章

  1. Any gotchas at all with converting from MyISAM to InnoDB?
  2. D. Equalize the Remainders (set的基本操作)
  3. Ubuntu14.04 换源 阿里云
  4. Spring学习-- SpEL表达式
  5. lhgdialog的传值问题
  6. netty学习指南
  7. [bzoj2251][2010Beijing Wc]外星联络——后缀数组+暴力求解
  8. bzoj 1996 DP
  9. 时间模块(time/date)
  10. Linux中实现一个简单的进度条【转】