ACM题目————次小生成树
Description
最小生成树大家都已经很了解,次小生成树就是图中构成的树的权值和第二小的树,此值也可能等于最小生成树的权值和,你的任务就是设计一个算法计算图的最小生成树。
Input
存在多组数据,第一行一个正整数t,表示有t组数据。
每组数据第一行有两个整数n和m(2<=n<=100),之后m行,每行三个正整数s,e,w,表示s到e的双向路的权值为w。
Output
输出次小生成树的值,如果不存在输出-1。
Sample Input
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
Sample Output
4 6
克鲁斯卡尔算法。
求一次是最小生成树,两次就是次小生成数了。
//Asimple #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <cctype> #include <cstdlib> #include <stack> #include <cmath> #include <string> #include <queue> #define INF 100000 using namespace std; const int maxn = 210; typedef long long ll ; int fa[maxn];//并查集 int vis[maxn];//记录下标 int path;//记录最小生成树用到边的数量 int T, n, m; typedef struct node{ int st; int ed; int w; bool operator < (const node& A) const { return w<A.w ; } }node; //初始化 void init(){ //获取并查集的大小 int len = sizeof(fa)/sizeof(fa[0]); for(int i=0; i<len; i++){ fa[i] = i; } } //并查集的查找——查找父节点 int findfa(int x){ int pa; if( x == fa[x] ) return x; pa = findfa(fa[x]); fa[x] = pa; return pa; } //求最小生成树 int minTree(node *points, int m, int n) { init(); int i, count, flag, pa, pb; for (i = count = flag = path = 0; i < m; i ++) { pa = findfa(points[i].st); pb = findfa(points[i].ed); if (pa != pb) { vis[path ++] = i; fa[pa] = pb; count ++; } if (count == n - 1) { flag = 1; break; } } return flag; } // 求次小生成树 int secMinTree(node *points, int m, int n) { int i, j, min, tmp, pa, pb, count, flag; for (i = 0, min = INF; i < path; i ++) { init(); // 求次小生成树 for (j = count = tmp = flag = 0; j < m; j ++) { if (j != vis[i]) { pa = findfa(points[j].st); pb = findfa(points[j].ed); if (pa != pb) { count ++; tmp += points[j].w; fa[pa] = pb; } if (count == n - 1) { flag = 1; break; } } } if (flag && tmp < min) min = tmp; } min = (min == INF) ? -1 : min; return min; } int main(){ node *p; scanf("%d",&T); while( T -- ){ scanf("%d %d",&n, &m); p = (node *)malloc(sizeof(node) * m); for(int i=0; i<m; i++){ scanf("%d %d %d",&p[i].st,&p[i].ed,&p[i].w); } sort(p,p+m); int f = minTree(p,m,n); if( f == 0 ){//无法生成最小生成树 printf("-1\n"); continue; } else { int Min = secMinTree(p,m,n); printf("%d\n",Min); } //释放p free(p); } return 0; }
低调做人,高调做事。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理