解题报告:最小生成树是否唯一判断方法
(1)图中每条边,扫描其他边,如果存在权值相同的边,则对其边标记
(2)用kruskal或prim算法求最小生成树的权值
(3)得到最小生成树,如果该最小生成树不包含标记的边,则最小生成树唯一,如果包含了标记的边,则依次去掉标记的边,再求最小生成树,如果求得的最小生成树与原最小生成树的权值相同,则最小生成树不唯一
code:
#include<cstdio> #include<cstring> #include<algorithm> #define maxn 105 #define INF 0x7fffffff using namespace std; struct node { int u, v, w; int equal; int used; int del; }edge[maxn*maxn]; int parent[maxn]; int n, m; bool first; bool cmp( const node &a, const node &b) { return a.w < b.w; } void UFset( ) { for(int i = 0; i <= n; i++) parent[i] = -1; } int Find( int x ) { int s ; for( s = x; parent[s] >= 0; s = parent[s] ); while(s != x ) { int temp = parent[x]; parent[x] = s; x = temp; } return s; } void Union( int R1, int R2 ) { int r1 = Find(R1); int r2 = Find(R2); int temp = parent[r1] + parent[r2]; if(parent[r1] > parent[r2]) { parent[r1] = r2; parent[r2] = temp; } else { parent[r2] = r1; parent[r1] = temp; } } int kruskal( ) { UFset( ); int i, j; int u, v; int sumweight = 0, num = 0; for( i = 0; i <m; i++ ) { if(edge[i].del == 1 ) continue; u = edge[i].u; v = edge[i].v; if( Find(u) != Find(v) ) { sumweight += edge[i].w; num++; Union( u, v ); if( first ) edge[i].used = 1; } if( num >= n-1 ) break; } return sumweight; } int main( ) { int T, u, v, w, j, i; scanf("%d",&T); while( T-- ) { memset(edge, 0, sizeof(edge) ); scanf("%d%d", &n, &m); for( i = 0; i < m; i++ ) { scanf("%d%d%d", &u, &v, &w); edge[i].u = u; edge[i].v = v; edge[i].w = w; } for(i = 0; i < m; i++ ) { for( j = 0; j < m; j++ ) { if( i == j ) continue; if( edge[i].w == edge[j].w ) edge[j].equal = 1; } } sort(edge, edge + m, cmp); first = true; int ans1 = kruskal( ); int ans2; first = false; for( i = 0; i < m; i++ ) { if(edge[i].used && edge[i].equal ) { edge[i].del = 1; ans2 = kruskal( ); if(ans1 == ans2 ) { printf("Not Unique!\n"); break; } edge[i].del = 0; } } if( i >= m ) printf("%d\n", ans1); } return 0; }
相关推荐
先利用prim算法求出最小生成树,然后通过往MST里加边来判断新生成的最小生成树是否具有最小的权值,POJ上The Unique MST(1679)题是要求判断最小生成树是否唯一,此题其实根本不用这样做,但是为了练习球次小生成树...
### 最小生成树(MST)问题详解 #### 一、最小生成树概念 最小生成树(Minimum Spanning Tree, MST)问题是计算机科学与图论领域中的一个重要问题,尤其是在网络设计、电路板布线等领域有着广泛的应用。对于一个连通的...
标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...
标题 "POJ 1751 求最小生成树Prim算法(JAVA)" 提到的是一个编程挑战,涉及图论中的经典算法——Prim算法。在计算机科学中,Prim算法是用于寻找加权无向图的最小生成树的一种有效方法。最小生成树是一棵树形结构,...
标题中的“POJ 1789 最小生成树之prim算法”指的是一个在线编程竞赛题目,来源于普林斯顿开放在线课程(POJ)平台。该题目要求参赛者实现Prim算法,这是一种解决图论问题中寻找最小生成树的经典算法。最小生成树是在...
这些题目均涉及到图论中的一个核心概念——最小生成树(Minimum Spanning Tree, MST),它在计算机科学,尤其是网络设计和优化问题中有着广泛应用。最小生成树问题是寻找一个无权图或有权图中的边的子集,这个子集...
然后,你需要实现克鲁斯卡尔算法的主要步骤,包括边的排序、初始化并查集、遍历排序后的边并判断是否形成环路以及加入最小生成树。最后,输出最小生成树的总权重。 以下是克鲁斯卡尔算法的基本步骤: 1. 初始化并...
2. **函数ALL_MST()**:遍历所有连通分量,调用`mst`函数计算各个连通分量的最小生成树,并将特殊节点s与各个连通分量的最小权值边加入生成树中。 3. **函数buildgraph(int m)**:读入原始图的数据,构建邻接矩阵`p...
5. **度限制最小生成树构建**:最终的`DL_MST()`函数将上述步骤综合起来,完成度限制最小生成树的构建。它首先通过DFS确定连通分量,然后在每个连通分量内调用Prim算法得到局部最小生成树,最后通过扩展Prim算法确保...
3. **P1679(Unique_MST_prim).cpp 和 P1679(Unique_MST_kruskal).cpp** - 这两个文件都涉及了“唯一最小生成树”问题。Prim和Kruskal是两种常见的求解最小生成树的算法。在某些情况下,图可能有唯一的最小生成树...
### POJ1679 TheUniqueMST **题目链接:** <http://acm.pku.edu.cn/JudgeOnline/problem?id=1679> **核心知识点:** - **问题描述:** 验证给定图的最小生成树是否唯一。 - **解题思路:** 可以先通过Prim或...
从提供的压缩包子文件名称"PKU_1861_最小生成树"来看,我们可以推测这道题目与图论中的"最小生成树"(Minimum Spanning Tree, MST)问题有关。最小生成树是图论中的一个重要概念,它要求找到一个无向加权图的边子集...
【标题】"POJ 1861 Network"是一个经典的计算机科学问题,它涉及到图论中的网络连接,并要求我们利用并查集(Disjoint Set)数据结构来检测图中的环路,同时应用快速排序算法来求解最小生成树。这个问题在ACM(国际...
在【压缩包子文件的文件名称列表】中,"poj 2485 Highways (最小生成树)"可能是题目提供的样例输入和输出文件,用于检验自己编写的程序是否正确。这些样例通常包含了各种边界情况和特殊案例,以确保算法的鲁棒性。 ...
【标题】"POJ1426-Find The Multiple【BFS+同余模】"是一道来源于北京大学在线编程平台POJ的算法题目,主要涉及到了广度优先搜索(BFS)与同余模运算的知识点。这道题目要求解决的是寻找一个整数的倍数问题,可能...
poj 1611 The Suspects 代码 并查集的应用
最小生成树(Minimum Spanning Tree, MST)是图论中的一个经典问题。在一个加权的无向图中,如果能找到一个子图,它包含原图的所有顶点,并且所有顶点都通过边互相连接,但没有任何回路存在,那么这个子图称为该图的...
2. **POJ1679 TheUniqueMST** - **题意**:判断最小生成树是否唯一。 - **解法**:Prim算法即可解决,虽然实现起来容易出错。 3. **POJ2728 DesertKing** - **题意**:要求找到具有最优比率的生成树。 - **...
【标题】"POJ1027 - The Same Game"是一个经典的编程竞赛题目,源自北京大学的在线编程平台POJ(Problem Online Judge)。该题目主要考察的是动态规划和矩阵链乘法的知识,要求参赛者编写程序解决一个具有策略性的...
2. 每次迭代:在未加入到最小生成树的顶点中,找到与已加入顶点相连的边中权值最小的一条,将这条边的另一端顶点加入到最小生成树中。 3. 重复步骤2,直到所有顶点都加入到最小生成树中,或者没有未加入顶点的边。 ...