poj 1679 The Unique MST

点击打开链接poj 1679

思路:最小生成树+次小生成树
分析:判断最小生成树是否是唯一的,那就可以去判断次小生成树是否大于最小生成树。这里就涉及到了次小生成树的求法
求解次小生成树:
step 1.  先用prim求出最小生成树T.
             在prim的同时,用一个矩阵max[u][v] 记录 在T中连结任意两点u,v的唯一的
             路中权值最大的那条边的权值. (注意这里).
             这是很容易做到的,因为prim是每次增加一个结点s, 而设已经标号了的结点
             集合为W, 则W中所有的结点到s的路中的最大权值的边就是当前加入的这条边.
             step 1 用时 O(V^2).
step 2.  枚举所有不在T中的边uv, 加入边uv则必然替换权为max[u][v]的边。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1010
#define INF 0XFFFFFFF

int t , n , m;
int vis[MAXN];
int pre[MAXN];/*记录节点的上一个节点*/
int lowcost[MAXN];
int maxvalue[MAXN][MAXN];
int G[MAXN][MAXN];
int mark[MAXN][MAXN];/*标记还有哪些边没被用*/

/*初始化*/
void init(){
    memset(mark , 0 , sizeof(mark));
    memset(maxvalue , 0 , sizeof(maxvalue));
    for(int i = 1 ; i <= n ; i++){
        pre[i] = 1;/*把所有点的上一点都记录为1*/
        for(int j = 1 ; j <= n ; j++)
           G[i][j] = INF;
    }
}

/*prime算法*/
void prime(){
     /*求解最小生成树*/
     memset(vis , 0 , sizeof(vis));
     int ans , pos , min;
     ans = 0;
     vis[1] = 1;
     for(int i = 1 ; i<= n ; i++)
         lowcost[i] = G[1][i];
     for(int i = 1 ; i <= n ; i++){
         pos = -1;
         for(int j = 1 ; j <= n ; j++){
            if(!vis[j] && (pos == -1 || lowcost[j] < lowcost[pos]))
              pos = j;
         }
         vis[pos] = 1;
         ans += lowcost[pos];
         mark[pre[pos]][pos] = mark[pos][pre[pos]] = 0;
         for(int j = 1 ; j <= n ; j++){
             if(vis[j])/*记录maxalue数组*/
                 maxvalue[j][pos] = maxvalue[pos][j] = lowcost[pos];
             if(!vis[j] && lowcost[j] > G[j][pos]){
                 lowcost[j] = G[j][pos];
                 pre[j] = pos;/*记录这些点的上一个节点*/
             }
         }
     }
     /*求解次小生成树*/
     min = INF;
     for(int i = 1 ; i <= n ; i++){
        for(int j = 1 ; j <= n ;j++){
           if(mark[i][j]){
             int tmp = ans-maxvalue[i][j]+G[i][j];
             if(tmp < min)
                 min = tmp;
             mark[i][j] = mark[j][i] = 0;
           }
        }
     }
     if(ans < min)/*如果不同则说明最小生成树是唯一的*/
         printf("%d\n" , ans);
     else
         printf("Not Unique!\n");
}

int main(){
    int x , y , v;
    scanf("%d" , &t);
    while(t--){
       scanf("%d%d" , &n , &m);
       init();
       for(int i = 0 ; i < m ; i++){
          scanf("%d%d%d" , &x , &y , &v);
          if(G[x][y] > v){
              G[x][y] = G[y][x] = v;
              mark[x][y] = mark[y][x] = 1;
          }
       }
       prime();
    }
    return 0;
}
时间: 2025-01-27 16:45:20

poj 1679 The Unique MST的相关文章

poj 1679 The Unique MST:次小生成树

链接: http://poj.org/problem?id=1679 题目: 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

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

无向连通图(无重边),判断最小生成树是否唯一,若唯一求边权和. 分析生成树的生成过程,只有一个圈内出现权值相同的边才会出现权值和相等但"异构"的生成树.(并不一定是最小生成树) 分析贪心策略求最小生成树的过程(贪心地选最短的边来扩充已加入生成树的顶点集合U),发现只有当出现"U中两个不同的点到V-U中同一点的距离同时为当前最短边"时,才会出现"异构"的最小生成树. 上图为kruscal和prim生成过程中可能遇到的相等边的情况,红色和蓝色的为权值

poj 3206 Borg Maze MST

    很无聊的题目,先bfs求下最短,再prim,输入还有多余空格--懒得敲了,随便找了个代码. 以下代码从http://hi.baidu.com/00gfzs/item/6dd7bf221b955c404799624a转载 #include <iostream> #include <queue> #include <cstring> #include <cstdio> using namespace std; int Val[102]; //prim记录

poj 1789 Truck History MST

   prim /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #define

poj 1251 Jungle Roads MST

   水 /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #defin

最小生成树【完结】

第一题 hdu 1232 畅通工程 点击打开hdu 1232 思路:模板题 点击查看代码 第二题 hdu 1233 还是畅通工程 点击打开hdu 1233 思路:模板题 点击查看代码 第三题 uva 10034 Freckles 点击打开uva 10034 思路:模板题 点击查看代码 第四题 uva 10397 Connect the Campus 点击打开uva 10397 思路:模板题 点击查看代码 第五题 uva 10369 Arctic Network 点击打开uva 10369 思路:

最小生成树

                                                                                                                       最小生成树 1概述: 在一个具有几个顶点的连通图G中,如果存在子图G'包含G中所有顶点和一部分边,且不形成回路,则称G'为图G的生成树,代价最小生成树则称为最小生成树. 许多应用问题都是一个求无向连通图的最小生成树问题.例如:要在n个城市之间铺设光缆,主要目标是

poj 1861 Network MST

    期末后第一次写题,结果就是这么灵异的一题--     样例是错的,这题实际上就是求个最小生成树,spj /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #includ

poj 1751 Highways MST

   水到家的一道题,居然WA了3次--没注意到距离是double--没有输出的话要输出一行空行  /* author:jxy lang:C/C++ university:China,Xidian University **If you need to reprint,please indicate the source** */ #include <iostream> #include <cstdio> #include <cstdlib> #include <