九度OJ 1249:次小生成树 (次小生成树)
时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:203
解决:56
- 题目描述:
-
最小生成树大家都已经很了解,次小生成树就是图中构成的树的权值和第二小的树,此值也可能等于最小生成树的权值和,你的任务就是设计一个算法计算图的最小生成树。
- 输入:
-
存在多组数据,第一行一个正整数t,表示有t组数据。
每组数据第一行有两个整数n和m(2<=n<=100),之后m行,每行三个正整数s,e,w,表示s到e的双向路的权值为w。
- 输出:
-
输出次小生成树的值,如果不存在输出-1。
- 样例输入:
-
2
3 3
1 2 1
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2
- 样例输出:
-
4
6
思路:
求给定图的次小生成树。
对于给定的图,我们可以证明,次小生成树可以由最小生成树变换一边得到。那么我们可以如下求给定图的次小生成树。首先,我们用prime算法求出图的最小生成树,在这个过程中记录每条边是否用过,以及两个点之间最短路径上的最大权值F[i,j]
F[i,j]可以如此求得,当加入点u的时候,并且u的父结点是v 那么对于已经在生成树中的节点x
F[x,u] = max(F[x,v], weight[u][v]),那么我么就可以用Prime算法一样的时间复杂度来求出图的次小生成树。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #define INF 0x3f3f3f3f int T, n, m;
int G[110][110], F[110], M[110][110], mark[110]; int max(int x, int y) {
return x > y ? x : y;
} void dfs(int src, int pre, int now) {
if (mark[now]) return;
//printf("dfs %d %d\n", src, now); if (src == now) {
M[src][now] = M[now][src] = 0;
}else {
M[src][now] = max(G[pre][now], M[src][pre]);
M[now][src] = M[src][now];
//printf("update M(%d,%d) = %d\n", now, src, M[src][now]);
} mark[now] = 1; int i;
for (i=1; i<=n; i++)
if (F[i] == now || F[now] == i) {
dfs(src, now, i);
}
} int main()
{
scanf("%d", &T); while (T--) {
scanf("%d%d", &n, &m); memset(G, INF, sizeof G);
int i, j;
for (i=0; i<m; i++) {
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
G[a][b] = G[b][a] = c;
} // prim
int dist[110], min_sum=0;
memset(dist, INF, sizeof dist);
memset(F, -1, sizeof F);
memset(mark, 0, sizeof mark);
dist[1] = 0;
while (1) {
j = 0;
for (i=1; i<=n; i++)
if (!mark[i] && dist[i] < dist[j]) j = i; if (j == 0) break;
min_sum += dist[j];
mark[j] = 1; for (i=1; i<=n; i++)
if (!mark[i] && dist[i] > G[j][i]) {
dist[i] = G[j][i];
F[i] = j;
}
} // now we get the max_path of i to j
memset(M, 0, sizeof M);
for (i=1; i<=n; i++) {
memset(mark, 0, sizeof mark);
dfs(i, i, i);
} int ans = INF;
// try delete i-j
for (i=1; i<=n; i++)
for (j=1; j<=n; j++) {
if (i!=j && F[j] != i && F[i] != j && min_sum + G[i][j] - M[i][j] < ans) {
ans = min_sum + G[i][j] - M[i][j];
//printf("ans : min_sum + G[%d][%d] - M[%d][%d] = %d\n", i, j, i, j, ans);
}
} printf("%d\n", ans);
} return 0;
} /**************************************************************
Problem: 1249
User: warcraftw
Language: C
Result: Accepted
Time:20 ms
Memory:1008 kb
****************************************************************/
九度OJ 1249:次小生成树 (次小生成树)的更多相关文章
- 九度oj 题目1087:约数的个数
题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...
- 九度OJ 1502 最大值最小化(JAVA)
题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...
- 九度OJ,题目1089:数字反转
题目描述: 12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转. 输入: 第一行一个正整数表示测试数据的个数n. ...
- 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)
题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...
- 九度OJ 1531 货币面值(网易游戏2013年校园招聘笔试题) -- 动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1531 题目描述: 小虎是游戏中的一个国王,在他管理的国家中发行了很多不同面额的纸币,用这些纸币进行任意的组合可以在 ...
- 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)
题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述: 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但 ...
- 九度OJ 1371 最小的K个数 -- 堆排序
题目地址:http://ac.jobdu.com/problem.php?pid=1371 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4 ...
- 九度OJ 题目1384:二维数组中的查找
/********************************* * 日期:2013-10-11 * 作者:SJF0115 * 题号: 九度OJ 题目1384:二维数组中的查找 * 来源:http ...
- hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
随机推荐
- Python 把u'\xca\xd3\xc6\xb5\xd7\xa5\xc8\xa1' 输出正常中文
今天碰见从数据库读取出来数据是u'\xca\xd3\xc6\xb5\xd7\xa5\xc8\xa1',输出显示乱码,经常查询处理如下: 两种方式: 1. s = u'\xca\xd3\xc6\xb5\ ...
- Spark-Streaming之window滑动窗口应用
Spark-Streaming之window滑动窗口应用,Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据,会被 ...
- iOS小技巧 - 如何使UIView可以绑定点击事件
让我们这次直接进入正题,有时候我们想做以下这种界面: 目前我就想到三种方案: 做一个tableview,然后组织cell的界面如上图所示 做一个button子类,使得button的界面能如上图所示 做 ...
- Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别
过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...
- 蓝的成长记——追逐DBA(5):不谈技术谈业务,恼人的应用系统
***************************************声明*************************************** 个人在oracle路上的成长记录,当中 ...
- Angular 学习笔记——ng-disable
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <met ...
- Web用户的身份验证及WebApi权限验证流程的设计和实现(尾)
5. WebApi 服务端代码示例 5.1 控制器基类ApiControllerBase [csharp] view plaincopy /// /// Controller的基类,用于实现适合业 ...
- centos安装pip Xvfb Selenium
pip安装命令: python -V wget https://bootstrap.pypa.io/get-pip.py python get-pip.py Xvfb安装命令: yum install ...
- java.String中的方法
(String) str.trim() 该方法返回一个复制该字符串的开头和结尾的白色空格去掉,或字符串,如果它没有头或尾空白. (Boolean) str.contains(str1) 判断 str ...
- iOS GCD不同场景的使用比較
/** * async -- 并发队列 * 会创建线程.一般同一时候开多条 * 并发运行任务 */ <span style="font-size:14px;"> ...