kruskal(拓展)

时间:2022-10-06 23:11:00

kruskal是最小生成树的一种做法,即严格按照贪心思想将边从小到大排序,一个一个枚举能不能加入图中,知道生成一棵树,显然树为最小树。

鄙人觉得kruskal做法远不止如此,那种严格从小到大选边的做法还有大用途...

例题:

kruskal(拓展)

此题也是生成一棵树,只不过生成一颗树边的最大值减最小值最小的树。那就有点难办...

这是我们就可以从题目要找的树本身入手思考,题目要求的树中有最大边与最小边,假设我们知道最小边,我们就可以用贪心的思想依次选择比最小边大但离最小值最近的边看是否能加入图中.即以最小边为基准找边。可是连最小边也不知道,怎么办?只能枚举了,即枚举每一条边当做基准,依次将比它大的边判断后入图,这就用到kruskal了,先按边小到大排序,依次枚举每一个边当基准,向后找生成树,更新找到的最小边差。

#include<bits/stdc++.h>
using namespace std;
int n,m,f[],tot,pd,cnt;
struct bian
{
int x,y,v;
};
bian a[];
inline int read()
{
int x=,ff=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*ff;
}
int getf(int k)
{
if(k==f[k]) return k;
else return (f[k]=getf(f[k]));
}
bool paixu(bian x,bian y)
{
return (x.v<y.v);
}
inline void work1()
{
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=tot;i++)
{
int x=getf(a[i].x);
int y=getf(a[i].y);
if(x!=y) f[x]=y;
}
int ans=getf();
for(int i=;i<=n;i++)
{
if(getf(i)!=ans)
{
pd=;
break;
}
}
}
inline void work2()
{
sort(a+,a++tot,paixu);
int minn=;
for(int i=;i<=tot-n+;i++)
{
int ans=-,cnt=,b=a[i].v;
for(int k=;k<=n;k++) f[k]=k;
for(int j=i;j<=tot;j++)
{
int x=getf(a[j].x);
int y=getf(a[j].y);
if(x!=y)
{
ans=max(ans,a[j].v-b);f[x]=y;
if(++cnt==n-) break;
}
}
//cout<<minn<<endl;
if(cnt==n-) minn=min(minn,ans);
}
cout<<minn<<endl;
}
int main()
{
//freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read(),v=read();
a[++tot].x=x;
a[tot].y=y;
a[tot].v=v;
}
work1();
if(pd==) {cout<<-<<endl;return ;}
work2();
return ;
}

这启示我们遇到边权差最小的树时可用kruskal解决.

下一题:

kruskal(拓展)

此题同样求最小边权差,只不过从特定的一点到另一点,不是全图的最小边权差.

怎么办呢?还从题目要求的情况考虑:从起点到终点是一个连通区域,我们用kruskal不断加边时,加入一个边就可以判断起点与终点是否连通,如果连通就没有继续加边的必要了,同时由于提前排好序的缘故,最后加的边一定是图中的最大边,且一定在从起点到终点的路径上(很显然,因为起点到终点是在加了此边才连通,没加之前起点与终点各是一个区域,而此边就是联通两个区域的唯一边,所以一定在路径上),

最大边找到了,剩下的就是最小边了,同样我们可以用枚举每条边当做基准,可是这又有问题,生成的图中,最小边可能不在路径内,如下图:

kruskal(拓展)

最小边为1,以1为基准可1不在路径中,算出的答案自然比正答大,可是如果1不在路径中,等到我们用2为基准时一定会遍历到这种情况,此时算出的答案就是正解了,可见这种解法并没有错。

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int n,m,T,f[maxn];
struct bian
{
int x,y,v;
};
bian a[maxn];
inline int read()
{
int x=,ff=;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') ff=-;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<)+(x<<)+(ch^);
ch=getchar();
}
return x*ff;
}
inline void put(int x)
{
if(x<) putchar('-'),x=-x;
if(x>) put(x/);
putchar(x%+'');
}
inline bool paixu(bian x,bian y)
{
return (x.v<y.v);
}
int getf(int x)
{
if(f[x]==x) return x;
else return(f[x]=getf(f[x]));
}
inline bool check(int qi,int zh)
{
for(int i=;i<=n;i++) f[i]=i;
for(int i=;i<=m;i++)
{
int t1=getf(a[i].x);
int t2=getf(a[i].y);
if(t1!=t2) f[t1]=t2;
}
if(getf(qi)==getf(zh)) return true;
else return false;
}
inline int work(int qi,int zh)
{
int minn=,maxx=,ans=INT_MAX;
for(int i=;i<=m;i++)
{
minn=a[i].v;maxx=;
for(int i=;i<=n;i++) f[i]=i;
for(int j=i;j<=m;j++)
{
int t1=getf(a[j].x);
int t2=getf(a[j].y);
if(t1!=t2)
{
f[t1]=t2;
if(getf(qi)==getf(zh))
{
maxx=a[j].v;
break;
}
}
}
if(maxx) ans=min(ans,maxx-minn);
}
return ans;
}
int main()
{
freopen("1.in","r",stdin);
n=read();m=read();
for(int i=;i<=m;i++)
{
a[i].x=read();
a[i].y=read();
a[i].v=read();
}
sort(a+,a++m,paixu);
T=read();
for(int i=;i<=T;i++)
{
int qi=read(),zh=read();
if(check(qi,zh)) put(work(qi,zh)),cout<<endl;
else put(),cout<<endl;
}
return ;
}

好了,kruskal就说到这了,如果做到有关边权差最小的题时,不要忘了kruskal了!

kruskal(拓展)的更多相关文章

  1. &lbrack;NOI2001&rsqb;食物链(并查集拓展域)&amp&semi;&amp&semi; &lbrack;HAOI2006&rsqb;旅行(Kruskal)

    题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B 吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的一种,但是我 ...

  2. &lbrack;luogu P4197&rsqb; Peaks 解题报告(在线:kruskal重构树&plus;主席树 离线:主席树&plus;线段树合并)

    题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...

  3. 【APIO2020】交换城市(Kruskal重构树)

    Description 给定一个 \(n\) 个点,\(m\) 条边的无向连通图,边带权. \(q\) 次询问,每次询问两个点 \(x, y\),求两点间的次小瓶颈路.不存在输出 -1. Hint \ ...

  4. C&plus;&plus;对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  5. RabbitMQ &plus; PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

  6. chrome拓展开发实战:页面脚本的拦截注入

    原文请访问个人博客:chrome拓展开发实战:页面脚本的拦截注入 目前公司产品的无线站点已经实现了业务平台组件化,所有业务组件的转场都是通过路由来完成,而各个模块是通过requirejs进行统一管理, ...

  7. 搭建LNAMP环境(七)- PHP7源码安装Memcached和Memcache拓展

    上一篇:搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展 一.安装Memcached 1.yum安装libevent事件触发管理器 yum -y install libe ...

  8. jQuery的DOM操作实例(2)——拖拽效果&amp&semi;&amp&semi;拓展插件

    一.原生JavaScript编写拖拽效果 二.jQuery编写的拖拽效果 三.在jQuery中拓展一个拖拽插件

  9. 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用

    图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...

随机推荐

  1. 第六次作业——利用MFC实现计算器图形界面以及简单四则运算表达式批处理

    参考资料:      1.MFC响应键盘      2.计算器实例      3.MFC文件对话框      4.MFCUpdateData()函数的使用      5.MFC教程      6.wi ...

  2. WritePrivateProfileString&lpar;&rpar;

    在我们写的程序当中,总有一些配置信息需要保存下来,以便完成程序的功能,最简单的办法就是将这些信息写入INI文件中,程序初始化时再读入.具体应用如下: 将信息写入.INI文件中 1.所用的WINAPI函 ...

  3. (二)&period; 细说Kalman滤波:The Kalman Filter

    本文为原创文章,转载请注明出处,http://www.cnblogs.com/ycwang16/p/5999034.html 前面介绍了Bayes滤波方法,我们接下来详细说说Kalman滤波器.虽然K ...

  4. http&colon;&sol;&sol;wenku&period;baidu&period;com&sol;link&quest;url&equals;UGoPtZviipHzi5SDIlGx6hPFWAHTPLFXcZ7ieD15JMd81DEHqjehvphVMhqELmOK4qXR74dTT9nW8VBoApBc7Kfb1ZWrNF&lowbar;i24fY1YRHVki

    http://wenku.baidu.com/link?url=UGoPtZviipHzi5SDIlGx6hPFWAHTPLFXcZ7ieD15JMd81DEHqjehvphVMhqELmOK4qXR ...

  5. DATASNAP倒底能承受多大的负载能力

    DATASNAP是针对企业数据中间件市场而推出来的产品,如果在其它领域用它可能就不会合适. DATASNAP通信使用INDY10,INDY是阻塞型SOCKET. 1.如果使用TCP/IP长连接,DAT ...

  6. ASP&period;NET MVC轻教程 Step By Step 1 ——入门

    使用ASP.NET MVC有一段时间了,本人还是非常喜欢ASP.NET MVC这个框架模式的.在经历了WebForm复杂粗暴的做法后,自然感觉简洁优雅的MVC清新可人,只不过WebForm和MVC的设 ...

  7. 【MSP是什么】MSP认证之项目管理与项目群管理的区别

    通常所说的项目管理是指运用各种相关知识.技能.方法与工具,为满足或超越项目有关各方对项目的要求与期望,所开展的各种计划.组织.领导.控制等方面的活动.具体包括项目范围管理.项目时间管理.项目成本管理. ...

  8. setTimeout,setInterval运行原理

      function a() { setTimeout(function(){alert(1)},0); alert(2); } a(); 和其他的编程语言一样,Javascript中的函数调用也是通 ...

  9. DOM中对象的获得

    DOM的所有对象会在页面打开时,由浏览器页面创建. 浏览器把dom定点对象Document对像的引用交给了window对象. 1.document对象的获得    var doc = window.d ...

  10. LINQ 按多个字段排序(orderby、thenby、Take)

    LINQ 按多个字段排序(orderby.thenby.Take) orderby  子句解析为 OrderBy()方法,orderby descending 子句解析为OrderBy Descend ...