UVA10600 次小生成树
题目链接:https://vjudge.net/problem/UVA-10600
题意:叫我们求出最小生成树的边权之和 和次小生成树的边权之和。
思路:我们可以先求出最小生成树,这个不难,如果要求次小生成树,那么我们肯定是要在最小生成树里面去掉一条边(假设是a),这样就变成两颗生成树了,我们就还要找一条边(假设是b)把这两颗树连接。这里我们需要满足的就是b-a最小(b一定大于a),这样找到的生成树就是次小生成树了是吧。
关键就是怎么更快的找到b和a这两条边的权值,使b-a最小。因为现在已经是最小生成树了,我们如果连接任意两点,那么根据树的性质,就一定会形成一个环了,那么我们肯定是去掉这个环里面除去边b之外的所有边里面权值最大的边,这样才可以在选择连接边b的情况下使重新生成的树的权值最小。然按照这个思路我们枚举每两点,就可以求出次小生成树了。
现在我们就要求出在最小生成树上每两点之间最大的边权,我们在这里用动态规划来实现,用maxx[i][j]来记录点i和点j之间最大的边权,在用prime算法来求最小生成树的时候,我们每增加一个点到树中,就求出这个点和已经加入树里面的所有点之间的maxx数组值,这里还要记录每个点的前驱,(假设点u的前驱就是pre[u],那么pre[u]就是在生成树里面和点u直接相连的并且在点u之前加入树中的点),那么假设现在我把点u加到树上,点j在点u之前就已经加在树上了,现在我要求出maxx[j][u],递推公式就是
maxx[j][u]=max(maxx[j][pre[u]],map[u][pre[u]]);也就是max(pre[u]和点j的maxx数组值,pre[u]和点u直接相连的边的权值);
看代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0xffffff
#define maxn 105
int n,m,k,t,ans1,ans2,sum;
int check[maxn][maxn],map[maxn][maxn],pre[maxn],vis[maxn],maxx[maxn][maxn],dis[maxn];
//check[i][j]表示最小生成树里i和j是否直接相连,map[i][j]记录i和j的边权
//pre[u]记录点u的前驱,maxx[i][j]记录点i和点j之间路径上权值最大的边
void init(){
memset(check,,sizeof(check));
memset(pre,,sizeof(pre));
memset(vis,,sizeof(vis));
memset(maxx,,sizeof(maxx));
for(int i=;i<n;i++){
for(int j=i+;j<=n;j++){
map[i][j]=map[j][i]=INF;
}
}
sum=;//记录最小生成树的边权和
ans1=ans2=INF;
}
void prime(){
for(int i=;i<=n;i++)
dis[i]=INF;
dis[]=;
for(int i=;i<=n;i++){
int u,min1=INF;
for(int j=;j<=n;j++){
if(!vis[j]&&dis[j]<min1){
min1=dis[j];
u=j;
}
}
vis[u]=;
sum+=min1;
check[pre[u]][u]=check[u][pre[u]]=;//把走过的边标记
for(int j=;j<=n;j++){
if(vis[j]&&j!=u){//用动态规划来计算点u和点j的maxx数组值
maxx[j][u]=maxx[u][j]=max(maxx[pre[u]][j],map[pre[u]][u]);
}
if(!vis[j]&&dis[j]>map[u][j]){
dis[j]=map[u][j];
pre[j]=u;
}
} }
}
void second(){//求次小生成树的权值和
for(int i=;i<n;i++){
for(int j=i+;j<=n;j++){
if(map[i][j]!=INF&&check[i][j]==){
ans2=min(ans2,sum+map[i][j]-maxx[i][j]);//去掉一条边,增加一条边
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
init();
int u,v,w;
for(int i=;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
map[u][v]=map[v][u]=min(map[u][v],w);
}
prime();
ans1=sum;
second();
printf("%d %d\n",ans1,ans2);
}
return ;
}
UVA10600 次小生成树的更多相关文章
- UVA-10600(次小生成树)
题意: 现在给一个图,问最小生成树和次小生成树的权值和是多少; 思路: 求最小生成树的两种方法,次小生成树是交换最小生成树的其中一条边得到的,现在得到了最小生成树,枚举不在次小生成树中的边,再求一边最 ...
- uva10600次小生成树模板题
裸题,上模板就行,注意j ! = k #include<map> #include<set> #include<cmath> #include<queu ...
- UVA10600:ACM Contest and Blackout(次小生成树)
ACM Contest and Blackout 题目链接:https://vjudge.net/problem/UVA-10600 Description: In order to prepare ...
- UVA10600 ACM Contest and Blackout —— 次小生成树
题目链接:https://vjudge.net/problem/UVA-10600 In order to prepare the “The First National ACM School Con ...
- UVA-10600 ACM Contest and Blackout (次小生成树)
题目大意:给一张无向图,找出最小生成树和次小生成树. 题目分析:模板题...方法就是枚举所有的比最小生成树中两端点之间的最长边还要长的边,用它替换,再取一个最小的值便是次小生成树了. 代码如下: # ...
- HDU 4081Qin Shi Huang's National Road System(次小生成树)
题目大意: 有n个城市,秦始皇要修用n-1条路把它们连起来,要求从任一点出发,都可以到达其它的任意点.秦始皇希望这所有n-1条路长度之和最短.然后徐福突然有冒出来,说是他有魔法,可以不用人力.财力就变 ...
- POJ1679 The Unique MST[次小生成树]
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 28673 Accepted: 10239 ...
- The Unique MST(次小生成树)
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22335 Accepted: 7922 Description Give ...
- URAL 1416 Confidential --最小生成树与次小生成树
题意:求一幅无向图的最小生成树与最小生成树,不存在输出-1 解法:用Kruskal求最小生成树,标记用过的边.求次小生成树时,依次枚举用过的边,将其去除后再求最小生成树,得出所有情况下的最小的生成树就 ...
随机推荐
- linux(ubuntu)共享文件夹
Linux系统的文件或目录的共享功能是非常强大,而且是非常灵活的,其对权限的控制可以做到非常的细致,当然如果你是通过命令行方式进行设置的 话,那么对于刚接触linux系统的用户来说将是一件十分头痛的事 ...
- memcached-redis
http://www.runoob.com/memcached/memcached-cas.html https://github.com/memcached/memcached/blob/maste ...
- [C#]typeof,Gettype()和is的区别
typeof 参数是一个类型名称,比如你自己编写的一个类 GetType()是类的方法,继承自object,返回该实例的类型 is 用来检测实例的兼容性(是否可以相互转换) 例: class Anim ...
- 代码问题:【CF2】
[CF2/CFCF/HCF]: C Ma, JB Huang, X Yang, et al. Hierarchical convolutional features for visual tracki ...
- Spark程序运行常见错误解决方法以及优化
转载自:http://bigdata.51cto.com/art/201704/536499.htm Spark程序运行常见错误解决方法以及优化 task倾斜原因比较多,网络io,cpu,mem都有可 ...
- Azure SQL 数据库仓库Data Warehouse (4) 2018 TechSummit 动手实验营
<Windows Azure Platform 系列文章目录> 上传一下之前在2018 TechSummit的动手实验营:Azure数据仓库PaaS项目架构规划与实战入门 包含PPT和Wo ...
- selenium +chromdriver模块
1 selenium 模拟浏览器行为 2 chromdriver 对应的chrome浏览器驱动 下载地址 注意:chrome与chromdriver存在对应关系 以下错误就可能是版本不对应 ...
- 2017-2018-2 20165312实验二《Java面向对象程序设计》实验报告
2017-2018-2 20165312实验二<Java面向对象程序设计>实验报告 实验中遇到的问题 1.增加MyUtil的测试类之后,TestCase是红色的,但是没有找到junit.j ...
- 刘志梅 201771010115 《面向对象程序设计(java)》 第八周学习总结
实验六 接口的定义与使用 实验时间 2018-10-18 1.实验目的与要求 (1) 接口定义:接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义:由常量和一组抽象方法组成:接 ...
- Android控件使用FragmentTabHost,切换Fragment;
大部分APP的主界面都很类似,要么底部导航的,要么就是侧滑菜单,还有底部导航+侧滑菜单的:底部导航实现大概有几种方式: TabHost+Fragment RadioGroup+Fragment Fra ...