The Unique MST POJ - 1679 (次小生成树)

Given a connected undirected graph, tell if its minimum spanning tree is unique.

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V‘, E‘), with the following properties: 
1. V‘ = V. 
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E‘) of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E‘.

Input

The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.

Output

For each input, if the MST is unique, print the total cost of it, or otherwise print the string ‘Not Unique!‘.

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

3
Not Unique!

求次小生成树 看与最小生成树是否相同 prime求次小生成树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 10010, INF = 0x7fffffff;
typedef long long LL;
int graph[510][510], d[maxn], vis[maxn], maxd[510][510], pre[maxn];
int n, m;

int prime(int s)
{
    int temp, sum = 0;
    mem(vis, 0);
    for(int i=1; i<=n; i++) d[i] = graph[s][i], pre[i] = s;
    vis[s] = 1;
    d[s] = 0;
    for(int i=1; i<n; i++)
    {
        int mincost = INF;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j] && mincost > d[j])
                mincost = d[j], temp = j;
        }
        for(int j=1; j<=n; j++)
            if(vis[j]) maxd[temp][j] = maxd[j][temp] = max(mincost, maxd[pre[temp]][j]);
        vis[temp] = 1;
        sum += mincost;
        for(int j=1; j<=n; j++)
        {
            if(!vis[j] && d[j] > graph[temp][j])
                d[j] = graph[temp][j], pre[j] = temp;
        }
    }
//    for(int i=1; i<=n; i++)
//        sum += d[i];
    return sum;
}

int main()
{
    int T;
    cin>> T;
    while(T--)
    {
        cin>> n >> m;
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
                if(i == j) graph[i][j] = 0;
                else graph[i][j] = graph[j][i] = INF;
        for(int i=0; i<m; i++)
        {
            int u, v, w;
            cin>> u >> v >> w;
            graph[u][v] = graph[v][u] = w;
        }
        int sum = prime(1);
        int lsum = INF;
        for(int i=1; i<=n; i++)
            for(int j=i+1; j<=n; j++)
            {
            if(i != pre[j] && j != pre[i]  && graph[i][j] != INF)
                if(sum - maxd[i][j] + graph[i][j] < lsum)
                    lsum = sum - maxd[i][j] + graph[i][j];
            }

        if(lsum == sum)
            cout<< "Not Unique!" <<endl;
        else
            cout<< sum <<endl;

    }

    return 0;
}



原文地址:https://www.cnblogs.com/WTSRUVF/p/9280124.html

时间: 2024-11-05 21:37:40

The Unique MST POJ - 1679 (次小生成树)的相关文章

The Unique MST POJ - 1679 次小生成树prim

求次小生成树思路: 先把最小生成树求出来  用一个Max[i][j] 数组把  i点到j 点的道路中 权值最大的那个记录下来 used数组记录该条边有没有被最小生成树使用过   把没有使用过的一条边加入最小生成树必然回形成一条回路   在这条回路中减去 除加入的边的权值最大的一条边  原图必然保持连通  (如果此时 权值最大的边和新加入的边权值相同  则存在 不同的最小生成树) 把每一条边加入再删除后 即可得出次小生成树 参考了: https://blog.csdn.net/qq_3395144

POJ 1679 The Unique MST 【最小生成树/次小生成树】

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22668   Accepted: 8038 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire

POJ 1679 次小生成树

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30015   Accepted: 10738 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undir

K - The Unique MST - poj 1679

题目的意思已经说明了一切,次小生成树... ************************************************************************************ #include<algorithm>#include<stdio.h>#include<string.h>#include<queue>using namespace std; const int maxn = 105;const int oo 

poj 2831 次小生成树模板

/*次小生成树 题意:给你一些路径,现在将一部分路径权值减少后问是否可以替代最小生成树里面的边. 解:次小生成树,即将这条边连上,构成一个环 求出任意两点路径之间的除了这条边的最大值,比较这个最大值>=这条边,说明可以替换. prime算法次小生成树模板 */ #include<stdio.h> #include<string.h> #define N 1100 #define inf 0x3fffffff int ma[N][N]; int Min(int a,int b)

poj 2831(次小生成树)

题意:给你一幅图,再给你Q个询问,每个询问为id cost,即如果将id这条边的边权改为cost的话,这条边是否可能是最小生成树中的一条边 解题思路:将第i条边(u,v)的权值修改的话,要判断是否是最小生成树中的一条边,首先要把它加入进去,此时必定会引起原来的生成树成环,所以必定要擦去一条边,擦去的是哪一条边,这就利用到了次小生成树的原理了. 之前写过一个次小生成树的题,现在回过头看,感觉又有点不对了. 这里再总结一次: 首先肯定是构造一颗最小生成树,接下来就是枚举不在生成树里的边,假定为(u,

poj1679次小生成树入门题

次小生成树求法:例如求最小生成树用到了 1.2.4这三条边,总共5条边,那循环3次的时候,每次分别不用1.2.4求得最小生成树的MST,最小的MST即为次小生成树 如下代码maxx即每次删去1,2,4边之后求得的最大边 #include<map> #include<set> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstd

POJ - 1679 The Unique MST (次小生成树)

Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the followin

POJ 1679:The Unique MST(次小生成树&amp;&amp;Kruskal)

The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 19941   Accepted: 6999 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undire