zoukankan      html  css  js  c++  java
  • The Unique MST

    The Unique MST Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u

    Submit Status

    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 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!
    
    也是最小生成树,问题是这个最小生成树的和,是不是可以由两条不同的路得到
    问题就转换成了求次小生成树的问题,看两个是否相等
    #include<iostream>
    #include<cstring>
    
    using namespace std;
    
    #define N 110
    #define INF 0xfffffff
    
    int n, maps[N][N], dist[N], pre[N], vis[N], Max[N][N], use[N][N];
    
    void init()
    {
        memset(vis, 0, sizeof(vis));  // 判断下标是否已经在树上
        memset(Max, 0, sizeof(Max));  // 求次小生成树的时候,要减去一条最大边加上一条最大边,还是保证每一个都联通,Max[i][j]数组存从i到j的已经在树上的联通路j到k, k到i两条路上边权值最大的一个
        memset(pre, 0, sizeof(pre));  // pre存下标是通过哪个点连到路上的
        memset(use, 0, sizeof(use));  // use从从i到j边权值是否被最小生成树用到
    
        for(int i = 1; i <= n; i++)
        {
            dist[i] = 0;
            for(int j = 1; j <= n; j++)
                maps[i][j] = maps[j][i] = INF;
            maps[i][i] = 0;
        }
    
    }  //  初始化
    
    int prim()
    {
        int s = 1;
        vis[s] = 1;
        dist[s] = 0;
        int ans = 0;
    
        for(int i = 1; i <= n; i++)
            dist[i] = maps[i][s], pre[i] = s;   // 从s点开始, s点先到树上
    
        for(int i = 1; i < n; i++)
        {
            int index, Min = INF;
    
            for(int j = 1; j <= n; j++)
                if(!vis[j] && dist[j] < Min)
                    Min = dist[j], index = j;  // 找当前连到树上所需边权值最小的点
    
            vis[index] = 1;
            ans += Min;  // 最小值连树,边权值ans总和加
            use[index][pre[index]] = use[pre[index]][index] = 1;  // 表示这个边权值以被最小生成树用,求次小生成树的时候不能用啦
    
            for(int j = 1; j <= n; j++)
            {
                if(vis[j] && index != j)
                    Max[j][index] = Max[index][j] = max(Max[j][pre[index]], dist[index]); 

           // 把可能更新的全更新了,Max找最大的从j到index的路,在j到index的前一点的最大值和index连到pre【index】上找
    if(!vis[j] && dist[j] > maps[j][index]) dist[j] = maps[j][index], pre[j] = index; // 更新最短路 } } return ans; } int MST(int sum) { int ans = INF; for(int i = 1; i <= n; i++) { for(int j = i+1; j <= n; j++) { if(!use[i][j] && maps[i][j] != INF) ans = min(ans, sum - Max[i][j] + maps[i][j]); // 找次小生成树,减去最小生成树上i到j最大的边,加上i到j的边权值,联通i,j。min是找较小的 } } return ans; } int main() { int t, m, x, y, w; cin >> t; while(t--) { cin >> n >> m; init(); while(m--) { cin >> x >> y >> w; maps[x][y] = maps[y][x] = w; } int num1 = prim(); int num2 = MST(num1); if(num1 != num2) cout << num1 << endl; // 如果最小生成树和次小生成树不等,就输出唯一的最小生成树的边权值之和,否则输出Not Unique! else cout << "Not Unique!" << endl; } return 0; }
    让未来到来 让过去过去
  • 相关阅读:
    linux下安装qt-4.5_for_TQ210_V1.0.(TQ210)-ubuntu11.10过程出现的问题
    15+ 易响应的CSS框架快速开启你的敏捷网站项目
    分享10个超实用的jQuery代码片段
    免费数据库+免费空间建站
    25个令人难忘的广告设计
    android实现点击效果
    ServletContextListener
    ServletContext
    一个不错的地址--类序列化等
    Java的运行时数据存储机制
  • 原文地址:https://www.cnblogs.com/Tinamei/p/4680237.html
Copyright © 2011-2022 走看看