该题是最小生成树问题变通活用,表示自己开始没有想到该算法:先将所有边按权重排序,然后枚举最小边,求最小生成树(一个简单图的最小生成树的最大权是所有生成树中最大权最小的,这个容易理解,所以每次取最小边,求一次最小生成树,这样差值都次这次最小的),记录更新即可。并查集来判断连通。

类似一提,hoj1598,开始时用DFS搜索,TLE,受启发,用枚举方法差不多,只是在每次枚举最小边的时候结束条件改为起点与终点连通,连通就结束(father(start)==father(end))。

#include<iostream>  //poj 3532  219MS
#include<cstring> //最小生成树有一个很重要的性质:在构造生成树时有可能选择不同的边,但最小生成树的权是唯一的!所以在用kruskal算法时第一次加入的必然是最小生成树的最小边权值,最小边确定后,最小生成树的最大边的权值是所以生成树中最小的,于是只要枚举最小边,然后求最小生成树,就可以得到最大边,只要每次更新最优解就行了。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct edge //边
{
int pre; //前一个点//一边的俩端点
int to; //后一个点
int w;
};
int best;int curmin,curmax;int fa[202];int flag=0;
bool my(const edge &a,const edge & b )
{
return a.w<b.w;
}
int father(int x)
{
return (x==fa[x]?x:father(fa[x]));
}
int main()
{ int n,m;
while(~scanf("%d%d",&n,&m)&&(m+n))
{
vector<edge>v(m);
int s,l,w;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&s,&l,&w);
v[i].to=l;
v[i].w=w;
v[i].pre=s;
}
sort(v.begin(),v.end(),my); //排序
best=1000001;flag=0;
for(int i=0;i<m;i++) //按从小到大枚举边
{
for(int ii=0;ii<=n;ii++) //初始化并查集
fa[ii]=ii;
int num=0;
curmin=v[i].w; curmax=-1;
for(int k=i;k<m;k++) //并查集判断联通
{
int xx=father(v[k].pre);
int yy=father(v[k].to);
if(xx!=yy) //连通性判断
{
if(curmax<v[k].w)
curmax=v[k].w;
if(curmax-curmin>best)break; //无此剪枝3000MS。
fa[xx]=yy;
num++;
}
}
if(i==0&&num!=n-1){flag=1;break;}
if(num==n-1&&best>curmax-curmin)
best=curmax-curmin;
}
if(flag||m==0){printf("-1\n");continue;}
else printf("%d\n",best);
}
return 0;
}

#include<iostream>  //100+MS
#include<cstring> //最小生成树有一个很重要的性质:在构造生成树时有可能选择不同的边,但最小生成树的权是唯一的!所以在用kruskal算法时第一次加入的必然是最小生成树的最小边权值,最小边确定后,最小生成树的最大边的权值是所以生成树中最小的,于是只要枚举最小边,然后求最小生成树,就可以得到最大边,只要每次更新最优解就行了。
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
struct edge //边
{
int pre; //前一个点//一边的俩个端点
int to; //后一个点
int w;
};
int best;int curmin,curmax;int fa[202];int flag=0;
bool my(const edge &a,const edge & b )
{
return a.w<b.w;
}
int father(int x)
{
return (x==fa[x]?x:father(fa[x]));
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
vector<edge>v(m);
int s,l,w;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&s,&l,&w);
v[i].to=l;
v[i].w=w;
v[i].pre=s;
}
sort(v.begin(),v.end(),my); //排序
int q;scanf("%d",&q);
while(q--)
{
int start,end;
scanf("%d%d",&start,&end);
best=1000001;
for(int i=0;i<m;i++) //按从小到大枚举边
{
flag=0;
for(int ii=0;ii<=n;ii++) //初始化并查集
fa[ii]=ii;
curmin=v[i].w; curmax=-1;
for(int k=i;k<m;k++) //并查集判断联通
{
int xx=father(v[k].pre);
int yy=father(v[k].to);
if(xx!=yy) //连通性判断
{
if(curmax<v[k].w)
curmax=v[k].w;
if(curmax-curmin>best)break; //无此剪枝300+MS。
fa[xx]=yy;
}
if(father(start)==father(end)){ flag=1;break;} //联通则退出
}
if(flag==0&&i==0){break;}
if(flag==1&&best>curmax-curmin)
best=curmax-curmin;
}
if(best==1000001||m==0){printf("-1\n");continue;}
else printf("%d\n",best);
}
}
return 0;
}

#include<iostream> //搜索TLE
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
struct edge
{
int pre;
int to;
int w;
};
int head[202];int mark[202];int best;int curmin,curmax;
int flag=0;
void dfs(int end,vector<edge>v,int cur,int shendu,int n)
{
if(best==0)return;
if(flag)return;
if(shendu==n){flag=1;return;}
if(curmax-curmin>=0&&curmax-curmin>=best)return;
if(cur==end)
{
if(curmax-curmin<best)
best=curmax-curmin;
return;
}
for(int i=head[cur];i!=-1;i=v[i].pre)
if(mark[v[i].to]==0)
{
int tempcurmin=curmin;int tempcurmax=curmax;
if(v[i].w<curmin)curmin=v[i].w;
if(v[i].w>curmax)curmax=v[i].w;
mark[v[i].to]=1;
dfs(end,v,v[i].to,shendu+1,n);
curmin=tempcurmin;
curmax=tempcurmax;
mark[v[i].to]=0;
}
return ;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
vector<edge>v(2*m);
int s,l,w;
memset(head,-1,sizeof(head)); for(int i=0;i<2*m;i++)
{
scanf("%d%d%d",&s,&l,&w);
v[i].to=l;v[i].w=w;
v[i].pre=head[s];
head[s]=i;
i++;
v[i].to=s;v[i].w=w;
v[i].pre=head[l];
head[l]=i;
}
int q;scanf("%d",&q);
int start,end;
while(q--)
{
scanf("%d%d",&start,&end);
memset(mark,0,sizeof(mark));
flag=0;
best=1000001;curmin=1000001;curmax=-1;
mark[start]=1;
dfs(end,v,start,1,n);
if(best==1000001)printf("-1\n");
else printf("%d\n",best);
} }
return 0;
}

poj3532求生成树中最大权与最小权只差最小的生成树+hoj1598俩个点之间的最大权与最小权只差最小的路经。的更多相关文章

  1. POJ2349(求生成树中符合题意的边)

    Arctic Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14977   Accepted: 4777 D ...

  2. POJ-2485 Highways---最小生成树中最大边

    题目链接: https://vjudge.net/problem/POJ-2485 题目大意: 求最小生成树中的最大边 思路: 是稠密图,用prim更好,但是规模不大,kruskal也可以过 #inc ...

  3. SSAS中事实表中的数据如果因为一对多或多对多关系复制了多份,在维度上聚合的时候还是只算一份

    SSAS事实表中的数据,有时候会因为一对多或多对多关系发生复制变成多份,如下图所示: 图1 我们可以从上面图片中看到,在这个例子中,有三个事实表Fact_People_Money(此表用字段Money ...

  4. UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别

    本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 现在,我们需要设计一个项目管理系统,目前我们收集到了如下这些需求: REQ1:一个项目内有多名项目成 ...

  5. Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  6. OpenFramework中视频或者图片进行中心旋转、平移、放大、缩小、矫正(本例以视频为准,只给出主要代码)

    /********** update mesh部分***********/ for(int i=0;i<4;i++) {  mesh[i].clear(); //重要,不加的话,移动视频的四个角 ...

  7. (转)Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别

    Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...

  8. hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)

    三态的基本概念: 1,  暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象 ...

  9. java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)

    CPU:10核 主频100MHz 1核  主频    3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...

随机推荐

  1. std::map插入已存在的key时,key对应的内容不会被更新

    std::map插入已存在的key时,key对应的内容不会被更新,如果不知道这一点,可能会造成运行结果与预期的不一致 “Because element keys in a map are unique ...

  2. HDU 4465 Candy (数学期望)

    题意:有两个盒子各有n个糖(n<=2*105),每天随机选1个(概率分别为p,1-p),然后吃掉一颗糖.直到有一天打开盒子一看,这个盒子没有糖了.输入n,p,求此时另一个盒子里糖的个数的数学期望 ...

  3. 推荐一个高大上的网易云音乐命令行播放工具:musicbox

    网易云音乐上有很多适合程序猿的歌单,但是今天文章介绍的不是这些适合程序员工作时听的歌,而是一个用Python开发的开源播放器,专门适用于网易云音乐的播放.这个播放器的名称为MusicBox, 特色是用 ...

  4. (转)使用CGLIB实现AOP功能与AOP概念解释

    http://blog.csdn.net/yerenyuan_pku/article/details/52864395 使用CGLIB实现AOP功能 在Java里面,我们要产生某个对象的代理对象,这个 ...

  5. 关于JDBC访问存储过程的问题

    最近开发一个应用,需要调用一个入参为List的存储过程. 存储过程为: proc_test(p1 OUT Number, p2 IN Number, p3 IN TAB_CUSTOMER); 这个Li ...

  6. axure使用经验

    泛化不常用======伸展也是拉动原件收缩也是拉动原件====== 动态模板相互影响(有的时候会出现这个问题,只需要设置两者的高度,不让两者有包含关系(一点点可以有):====== 实现高级菜单栏(同 ...

  7. zeromq编译与应用

    libzmq是c++语言开发的,正式版本在这里: https://github.com/zeromq/libzmq/releases 到这篇文件发布为止,正式稳定版是4.2.2 1,按照给出的链接下载 ...

  8. Educational Codeforces Round 59 (Rated for Div. 2) (前四题)

    A. Digits Sequence Dividing(英文速读) 练习英语速读的题,我还上来昏迷一次....只要长度大于2那么一定可以等于2那么前面大于后面就行其他no 大于2的时候分成前面1个剩下 ...

  9. C/C++连接MySQL数据库执行查询

    1. 简介: 使用C/C++连接MySQL数据库执行增删改查操作,基本就是围绕以下两个文件展开: mysql.h(此头文件一般在MySQL的include文件夹内,如 D:\MySQL\mysql-5 ...

  10. python基础知识08-类定义、属性、初始化和析构

    1.类的定义 class 类 是独立存放变量(属性/方法)的一个空间. 每个实例都是一个独立的变量空间.不同实例之间的空间互相不可见. 一个实例的特征,就是属性. 定义在类中的私有属性也可以被子类继承 ...