两个BUG鸣翠柳,一行代码上西天。。。

hdu4786 Fibonacci Tree(生成树)问能否用白边和黑边构成一棵生成树,并且白边数量是斐波那契数。

题解:分别优先加入白边和黑边,求出生成树能包含白边的最大值和最小值,其间有值为斐波那契数即可。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1e5+;
const int N=1e5+;
struct edge{
int u,v,w;
}e[M];
int f[N];
int fi[];
int n,m,ans;
int cmp(edge a,edge b){
return a.w<b.w;
}
void init(){
for(int i=;i<=n;++i) f[i]=i;
}
int fin(int x){
if(x!=f[x])f[x]=fin(f[x]);
return f[x];
}
void Kruskal(){
int u,v,i,cnt=,mi=,ma=,flag=;
init();
for(i=;i<m;++i){
u=e[i].u;
v=e[i].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
if(e[i].w) mi++;
if(++cnt==n-){flag=;break;}
}
}
if(!flag){printf("No\n");return;}
init();
for(i=m-;i>=;--i){
u=e[i].u;
v=e[i].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
if(e[i].w) ma++;
if(++cnt==n-)break;
}
}
for(i=;i<;++i)
if(mi<=fi[i]&&fi[i]<=ma){
printf("Yes\n");return;
}
printf("No\n");
}
int main(){
int t,i,a,b,c,k=;
fi[]=;fi[]=;
for(i=;i<;++i)
fi[i]=fi[i-]+fi[i-];
//printf(".%d.",fi[19]);
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(i=;i<m;++i){
scanf("%d%d%d",&a,&b,&c);
e[i]={a,b,c};
}
sort(e,e+m,cmp);
printf("Case #%d: ",k++);
Kruskal();
}
return ;
}

hdu5253 连接的管道(最小生成树)一开始我因为没建好图纠结了ToT~

 #include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=;
struct edge{
int u,v,w;
}e[N*N*];
int f[N*N];
int g[N][N];
int ei,n,m,ans;
int cmp(edge a,edge b){
return a.w<b.w;
}
int fin(int x){
if(x!=f[x])f[x]=fin(f[x]);
return f[x];
}
void Kruskal(){
int u,v,i,cnt=;
for(ans=i=;i<ei;++i){
u=e[i].u;
v=e[i].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
ans+=e[i].w;
if(++cnt==n*m-)break;
}
}
}
int main(){
int t,i,j,h,k=;
scanf("%d",&t);
while(t--){
ei=;
scanf("%d%d",&n,&m);
for(i=;i<n;++i){
for(j=;j<m;++j){
scanf("%d",&g[i][j]);
f[i*m+j]=i*m+j;
if(i>){
e[ei].u=i*m+j; e[ei].v=(i-)*m+j;
e[ei++].w=abs(g[i][j]-g[i-][j]);
}
if(j>){
e[ei].u=i*m+j; e[ei].v=i*m+j-;
e[ei++].w=abs(g[i][j]-g[i][j-]);
}
}
}
sort(e,e+ei,cmp);
Kruskal();
printf("Case #%d:\n%d\n",k++,ans);
}
return ;
}

hdu1598 find the most comfortable road(最小生成树,枚举)第一眼看过去差点想最短路[吓],,这是最小差不是最短路哦。用Kruskal要对边排序,贪心正好哩。枚举最小道路建树,起点和终点连上了就记录最大边与最小边之差,最后选所有情况的最小值就行啦。

 #include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
const int M=;
struct edge{
int u,v,w;
}e[M];
int f[];
int n,m,ans,st,ed;
int cmp(edge a,edge b){
return a.w<b.w;
}
void init(){
for(int i=;i<=n;++i)
f[i]=i;
}
int fin(int x){
if(x!=f[x])f[x]=fin(f[x]);
return f[x];
}
void Kruskal(){
int u,v,i,j;
ans=inf;
for(i=;i<m;++i){//枚举
init();
for(j=i;j<m&&e[j].w-e[i].w<ans;++j){
u=e[j].u;
v=e[j].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
}
if(fin(st)==fin(ed)){
ans=min(ans,e[j].w-e[i].w);
break;
}
}
}
}
int main(){
int i,j,q;
while(scanf("%d%d",&n,&m)==){
for(i=;i<m;++i)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e,e+m,cmp);
scanf("%d",&q);
while(q--){
scanf("%d%d",&st,&ed);
Kruskal();
printf("%d\n",(ans==inf)?-:ans);
}
}
return ;
}

poj3522 Slim Span(最小生成树,枚举)求最大边与最小边之差最小的生成树。和上面那题挺像的,相比之下,这题就是完整的最小生成树了。

 #include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=;
struct edge{
int u,v,w;
}e[];
int f[N];
int n,m,ans,st,ed;
int cmp(edge a,edge b){
return a.w<b.w;
}
void init(){
for(int i=;i<=n;++i)
f[i]=i;
}
int fin(int x){
if(x!=f[x])f[x]=fin(f[x]);
return f[x];
}
void Kruskal(){
int u,v,i,j,cnt;
ans=inf;
for(i=;i<m;++i){
init(); cnt=;
for(j=i;j<m&&e[j].w-e[i].w<ans;++j){
u=e[j].u;
v=e[j].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
if(++cnt==n-){
ans=min(ans,e[j].w-e[i].w);
break;
}
}
}
}
}
int main(){
int i,j,q;
while(scanf("%d%d",&n,&m),n||m){
for(i=;i<m;++i)
scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e,e+m,cmp);
Kruskal();
printf("%d\n",(ans==inf)?-:ans);
}
return ;
}

poj2784 Buy or Build(最小生成树,二进制枚举)英语渣在艰难地读题orz。已知n个城市的坐标,q个连通块各自的费用,新建一条边的费用为两点距离的平方。求最小生成树。学了一下二进制枚举法。

 #include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int N=;
struct edge{
int u,v,w;
}e[];
struct node{
int x,y;
}V[N];
int f[N];
int a[];
int n,m,q;
vector<int>g[];
int cmp(edge a,edge b){
return a.w<b.w;
}
int dist(int i,int j){
return (V[i].x-V[j].x)*(V[i].x-V[j].x)+(V[i].y-V[j].y)*(V[i].y-V[j].y);
}
void init(){
for(int i=;i<=n;++i)
f[i]=i;
}
int fin(int x){
if(x!=f[x])f[x]=fin(f[x]);
return f[x];
}
void uni(int x,int y){
if((x=fin(x))==(y=fin(y)))return;
f[x]=y;
}
int Kruskal(){
int u,v,i,j,cnt=,ans=;
for(i=;i<m;++i){
u=e[i].u;
v=e[i].v;
if((u=fin(u))!=(v=fin(v))){
f[u]=v;
ans+=e[i].w;
if(++cnt==n-)break;
}
}
//printf("%d..\n",ans);
return ans;
}
void solve(){
int i,j,k,cost,ans;
init();
ans=Kruskal();
for(i=;i<(<<q);++i){//枚举方案
cost=;
init();
for(j=;j<q;++j){
if(!((i>>j)&))continue;//二进制枚举
cost+=a[j];
//printf("COST:%d..",cost);
for(k=;k<g[j].size();++k)
uni(g[j][k],g[j][]);
}
ans=min(ans,cost+Kruskal());
}
printf("%d\n",ans);
}
int main(){
int i,j,num,x;
while(scanf("%d%d",&n,&q)==){
for(i=;i<q;++i){
g[i].clear();
scanf("%d%d",&num,&a[i]);
for(j=;j<num;++j){
scanf("%d",&x);
g[i].push_back(x);
}
}
for(i=;i<=n;++i) scanf("%d%d",&V[i].x,&V[i].y);
m=;
for(i=;i<n;++i){
for(j=i+;j<=n;++j){
e[m].u=i; e[m].v=j;
e[m++].w=dist(i,j);
}
}
sort(e,e+m,cmp);
solve();
}
return ;
}

最小生成树练习2(Kruskal)的更多相关文章

  1. 最小生成树之Prim Kruskal算法(转)

    最小生成树 首先,生成树是建立在无向图中的,对于有向图,则没有生成树的概念,所以接下来讨论的图均默认为无向图.对于一个有n个点的图,最少需要n-1条边使得这n个点联通,由这n-1条边组成的子图则称为原 ...

  2. 最小生成树(prim&kruskal)

    最近都是图,为了防止几次记不住,先把自己理解的写下来,有问题继续改.先把算法过程记下来: prime算法:                  原始的加权连通图——————D被选作起点,选与之相连的权值 ...

  3. 图的最小生成树(Prim、Kruskal)

    理论: Prim: 基本思想:假设G=(V,E)是连通的,TE是G上最小生成树中边的集合.算法从U={u0}(u0∈V).TE={}开始.重复执行下列操作: 在所有u∈U,v∈V-U的边(u,v)∈E ...

  4. 最小生成树模板【kruskal & prim】

    CDOJ 1966 Kruskal 解法 时间复杂度O(mlogm) m为边数,这里主要是边排序占时间,后面并查集还好 #include <cstdio> #include <cst ...

  5. 图-最小生成树算法之Kruskal及其Java实现

    1.Kruskal算法 Kruskal算法基于贪心,因此它追求的是近似最优解,也就是说由Kruskal得出的生成树并不一定是最优解. Kruskal算法求最小生成树的关键在于,每次选取图中权值最小(及 ...

  6. 最小生成树(II)与Kruskal算法

    为防止网页加载过慢,故分两章.上接https://www.cnblogs.com/Uninstalllingyi/p/10479470.html Kruskal算法——将森林合并成树 玩过瘟疫公司吗… ...

  7. 最小生成树算法 prim kruskal两种算法实现 HDU-1863 畅通工程

    最小生成树 通俗解释:一个连通图,可将这个连通图删减任意条边,仍然保持连通图的状态并且所有边权值加起来的总和使其达到最小.这就是最小生成树 可以参考下图,便于理解 原来的图: 最小生成树(蓝色线): ...

  8. poj1861 最小生成树 prim &amp; kruskal

    // poj1861 最小生成树 prim & kruskal // // 一个水题,为的仅仅是回味一下模板.日后好有个照顾不是 #include <cstdio> #includ ...

  9. 最小生成树 Prim算法 Kruskal算法实现

    最小生成树定义 最小生成树是一副连通加权无向图中一棵权值最小的生成树. 在一给定的无向图 G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即,而 w(u, v) 代表此边的 ...

  10. 最小生成树求法 Prim + Kruskal

    prim算法的思路 和dijkstra是一样的 每次选取一个最近的点 然后去向新的节点扩张 注意这里的扩张 不再是 以前求最短路时候的到新的节点的最短距离 而是因为要生成一棵树 所以是要连一根最短的连 ...

随机推荐

  1. DISPLAY_ITEM built-in in Oracle D2k Forms

    DISPLAY_ITEM built-in in Oracle D2k Forms DescriptionMaintained for backward compatibility only. For ...

  2. java读取文件多种方法

    1.按字节读取文件内容2.按字符读取文件内容3.按行读取文件内容 4.随机读取文件内容 public class ReadFromFile {     /**      * 以字节为单位读取文件,常用 ...

  3. XAF应用开发教程(四)应用程序模型

    XAF是重量型框架,确实够重量的,方方面面都做得规规矩矩. 如果看了前面三节,可能会认为,这N多的Attribute到底都是从哪里来的?到底有多少这样的Attribute?如果不够用了怎么办?等着官方 ...

  4. java中类名.class、实例.getclass()区别

    import java.util.HashSet; import java.util.Iterator; /** * Created by GOD on 2016/1/23. * Class对象的生成 ...

  5. BeanUtils框架的简单运用

    Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单.易用的API操作Bean的属性——BeanUtils Beanutils工具包的常用类: •BeanUt ...

  6. codeforces 300E Empire Strikes Back 数论+二分查找

    题意:给定N个数a1,a2,a3...aN,现在要求最小的n满足 n!/(a1!*a2!*...*aN!) 是一个正整数的最小的n. 分析:这题的想法很明确,就是分解a1!*a2!*...*aN!,把 ...

  7. 跨代的对决 英特尔i7-6700HQ对比i7-4720HQ性能测试

    http://itianti.sinaapp.com/index.php/cpu 跨代的对决 英特尔i7-6700HQ对比i7-4720HQ性能测试 2015-10-13 19:46:31 来源:电脑 ...

  8. ORACLE SQL 分组

    select max(cost),suppliercode from tel_bill where period = '2014005' group by suppliercode;select * ...

  9. 百度web前端面试2015.10.18

    邮件里通知的周日下午两点参加百度校招面试,我13:10分就到了,前台先让我拿了个面试资格单(上面是我的信息),然后在web前端面试入口排队,面试在百度食堂举行的,等了大概1个小时,放我去面试.都是一对 ...

  10. mysql 查询执行的流程

    1.客户端发送一个请求给服务器.2.服务器先检查查询缓存,命中了缓存,直接返回缓存中的数据,否则进入下一个阶段.3.服务器进行sql解析,预处理,再由优化器生成对应的执行计划.4.mysql根据执行计 ...