poj 1679 The Unique MST

简介: 点击打开链接poj 1679 思路:最小生成树+次小生成树 分析:判断最小生成树是否是唯一的,那就可以去判断次小生成树是否大于最小生成树。这里就涉及到了次小生成树的求法 求解次小生成树: step 1.

点击打开链接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;
}


目录
相关文章
|
缓存 监控 NoSQL
Redis - 在电商购物车场景下的实战分析
Redis - 在电商购物车场景下的实战分析
1445 0
|
机器学习/深度学习 弹性计算 网络协议
阿里云服务器ECS c9i实例收费价格:2核4G、4核8G和8核16G优惠配置整理
阿里云ECS计算型c9i实例,2核4G、4核8G、8核16G享优惠价,搭载Intel Xeon处理器,主频3.2GHz,适用于Web服务、机器学习等场景,ESSD云盘,网络性能强劲,限时活动价格低至181.73元/月。
897 95
|
8月前
|
人工智能 监控 安全
AI智能体的开发流程
开发AI智能体是从“调用模型”迈向“系统工程”的跃迁,强调感知-决策-执行闭环。涵盖目标拆解、四层架构(Brain/Planning/Memory/Tools)、工具集成、提示词工程、迭代评估与安全部署。非万能方案,固定流程仍宜用传统逻辑。
|
8月前
|
C语言
C语言深度短文:函数调用栈与栈帧原理(极简版)
很多人写C多年,却不懂函数调用的本质——栈帧。每次调用函数,CPU在栈上开辟空间保存返回地址、参数、局部变量等,即“栈帧”;函数返回即销毁该帧。局部变量快因在栈上,递归过深致栈溢出,返回局部变量地址则成野指针。懂栈帧,才真正理解C的运行机制。(239字)
|
存储 运维 安全
云服务器-进阶篇
本文全面对比了云服务器、物理服务器与VPS在技术架构、性能、成本及运维等方面的核心差异,通过表格和深度解析帮助用户理解各类型服务器的优劣势,从而根据具体场景做出最优选择。
|
消息中间件 安全 Java
Java“NoInitialContextException”问题解决
Java中“NoInitialContextException”异常通常发生在JNDI(Java命名和目录接口)查找时缺少初始上下文配置。解决方法包括:确保JNDI提供者URL正确、添加必要的库文件、配置jndi.properties文件或在代码中显式指定InitialContext环境属性。
530 1
|
人工智能 搜索推荐
影视与游戏行业AI视频制作实战:第二步,为角色生成个性化语音
每个角色有自己的性格、形象,那也一定需要自己个性化的声音。
|
Java
Java中的异常处理:深入理解try-catch语句
【6月更文挑战第15天】本文将深入探讨Java中的异常处理机制,特别是try-catch语句的使用。我们将通过实例来理解异常处理的重要性,以及如何在编程中有效地使用try-catch语句来捕获和处理异常。
742 3
|
SQL 安全 网络安全
数据安全之认识数据库防火墙
随着信息技术的快速发展,数据库已成为企业信息化建设的核心组成部分,存储着大量的关键业务数据和敏感信息。与此同时,数据库也面临着来自内部和外部的各种安全威胁和攻击,如SQL注入、未授权访问、数据泄露等。为了保护数据库的安全性和完整性,传统的安全措施如防火墙、入侵检测系统等在一定程度上起到了作用。然而,这些措施往往只关注于网络层面的安全防护,而缺乏对数据库应用层面的深入保护。因此,针对数据库的安全防护需求,数据库防火墙应运而生。
955 0