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架飞机运 ...
随机推荐
- 关于setTimeout和Promise执行顺序问题
先看一段代码 console.log('打印'+1); setTimeout(function(){ console.log('打印'+2); }) new Promise(function(reso ...
- JSP 错误处理方法
web.xml中配置error-page标签 1.WEB工程中打开 web.xml 文件
- LibreOJ #119. 最短路 (堆优化dijkstra)
题目描述 给一个 n(1≤2500≤n) n(1 \leq 2500 \leq n)n(1≤2500≤n) 个点 m(1≤6200≤m) m(1 \leq 6200 \leq m)m(1≤6200≤m ...
- 基于SAE的Python+Django部署
本文主要参考:http://www.cnblogs.com/qtsharp/archive/2012/01/12/2320774.html,另外包括自己的实际操作. 一.申请SAE帐号以及创建应用ya ...
- docker 新手入门(docker的安装)
docker的安装(在centos7下面) 1. 卸载在liunx下,先看有没有安装docker,docker version,如果有的话,可以先移除 yum remove ........ 可以使用 ...
- (转载)RedHat Enterprise Linux 5 安装GCC
注:在RedHat Enterprise Linux 5使用gcc编译第一个程序时,发现其gcc并未安装.在网上搜索看到这篇帖子.遂转到此处进行学习.感谢博客园中的“风尘孤客”的分享.@风尘孤客 Ab ...
- 通过JS加载XML文件,跨浏览器兼容
引言 通过JS加载XML文件,跨多种浏览器兼容. 在Chrome中,没有load方法,需要特殊处理! 解决方案 部分代码 try //Internet Explorer { xmlDoc=new Ac ...
- Spread / Rest 操作符
Spread / Rest 操作符指的是 ...,具体是 Spread 还是 Rest 需要看上下文语境. 当被用于迭代器中时,它是一个 Spread 操作符:(参数为数组) function foo ...
- 自定义分隔符|/i|/x|/xs|需要转译
小骆驼 第八章 用正则表达式进行匹配 #!/usr/bin/envperl use strict; use warnings; $_ ="#adchbehnyhme3534f\nvdh5ej ...
- C#中byte类型运算
首先看下面一段代码 byte x = 1; byte y = 2; byte z = x + y; Console.WriteLine(z); 可能很多人会说显示结果是3. 其实,这段代码无法运行,因 ...