poj3532求生成树中最大权与最小权只差最小的生成树+hoj1598俩个点之间的最大权与最小权只差最小的路经。
该题是最小生成树问题变通活用,表示自己开始没有想到该算法:先将所有边按权重排序,然后枚举最小边,求最小生成树(一个简单图的最小生成树的最大权是所有生成树中最大权最小的,这个容易理解,所以每次取最小边,求一次最小生成树,这样差值都次这次最小的),记录更新即可。并查集来判断连通。
类似一提,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俩个点之间的最大权与最小权只差最小的路经。的更多相关文章
- POJ2349(求生成树中符合题意的边)
Arctic Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14977 Accepted: 4777 D ...
- POJ-2485 Highways---最小生成树中最大边
题目链接: https://vjudge.net/problem/POJ-2485 题目大意: 求最小生成树中的最大边 思路: 是稠密图,用prim更好,但是规模不大,kruskal也可以过 #inc ...
- SSAS中事实表中的数据如果因为一对多或多对多关系复制了多份,在维度上聚合的时候还是只算一份
SSAS事实表中的数据,有时候会因为一对多或多对多关系发生复制变成多份,如下图所示: 图1 我们可以从上面图片中看到,在这个例子中,有三个事实表Fact_People_Money(此表用字段Money ...
- UML中关联(Association)、聚合(Aggregation)和合成(Composition)之间的区别
本文为 Dennis Gao 原创技术文章,发表于博客园博客,未经作者本人允许禁止任何形式的转载. 现在,我们需要设计一个项目管理系统,目前我们收集到了如下这些需求: REQ1:一个项目内有多名项目成 ...
- Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别
Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...
- OpenFramework中视频或者图片进行中心旋转、平移、放大、缩小、矫正(本例以视频为准,只给出主要代码)
/********** update mesh部分***********/ for(int i=0;i<4;i++) { mesh[i].clear(); //重要,不加的话,移动视频的四个角 ...
- (转)Spring中Bean的命名问题(id和name区别)及ref和idref之间的区别
Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...
- hibernate中持久化对象的生命周期(三态:自由态,持久态,游离态 之间的转换)
三态的基本概念: 1, 暂时状态(Transient):也叫自由态,仅仅存在于内存中,而在数据库中没有对应数据.用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫暂时对象 ...
- java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)
CPU:10核 主频100MHz 1核 主频 3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...
随机推荐
- 响应式布局 max-device-width 与 max-width 的区别
闲来没事,研究了一下多屏适配和响应式布局的 CSS. 第一种写法 @media screen and (max-device-width: 320px) { } @media screen and ( ...
- iOS 随笔 允许所有不安全网络访问项目
允许任意请求访问app App Transport Security Settings -> Allow Arbitrary Loads YES
- Load average in Linux的精确含义
Man 上的解释: load average System load averages is the average number of processes that are either in a ...
- 【C++】双边滤波器(bilateral filter)
Bilateral Filtering for Gray and Color Images 双边滤波器:保留边界的平滑滤波器. 在局部上,就是在灰度值差异不大的区域平滑,在灰度值差异比较大的边界地区保 ...
- System.currentTimeMillis()与日期之间的相互转换
System.currentTimeMillis()与日期 之间是可以相互转换的,大多数Android开发者都知道 通过 SimpleDateFormat dateformat = new Simpl ...
- springcloud 之 bus 消息总线
在分布式系统中,我们通常使用轻量级消息代理(rabbitmq.kafuka)建立一个公共的主题,让所有的微服务都链接进来,并且监听消费这个主题的内容,我们就称这个主题是 消息总线. (可以用作配置文件 ...
- 聊天室(C++客户端+Pyhton服务器)_1.框架搭设
聊天室 一.客户端发送 用MFC可视化做个客户端登录界面. 先点击注册账号按钮,注册账号的时候就需要连接到服务器, 服务器需要查数据库,并做出相应的回应. 所以开始写C++客户端套接口类用来连接到服务 ...
- 解决selenium.common.exception.WebDriverException:Message:'chromedriver' executable needs to be in Path
'chromedriver' executable needs to be in Path 声明:本人萌新,刚学python不久记录一下自己的坑,发出来若能帮助到一些人尽早解决问题那便是极好的,( ̄▽ ...
- python基础一 day5 知识点
Unicode转化为gbk和utf-8 表现形式:str转化为bytes
- 任务二:零基础HTML及CSS编码(一)
面向人群: 零基础或初学者 难度: 简单 重要说明 百度前端技术学院的课程任务是由百度前端工程师专为对前端不同掌握程度的同学设计.我们尽力保证课程内容的质量以及学习难度的合理性,但即使如此,真正决定课 ...