题意:

     判断最小树是否唯一。

思路:

     我用了两种方法,主要就是好久没敲了,找个水题练练手,第一种就是先一遍最小生成树,然后枚举最小生成树上的每一条边,然后取消这条边,在跑一遍最小生成树,就这样一直跑最小生成树,如果找到了一颗和之前的那个一样的,那么就是不唯一,第二种方法也是先最小树,然后枚举,在枚举的时候不是继续重新跑,而是断开当前边,把树分成两个集合<两次深搜实现>,然后在枚举这连个集合之间是否可以找到一个可以代替当前枚举的最小树的边,实现复杂度的话应该是第二种快点,但理论上也快不多少,只是为了练练手,在多说一句,第二种方法和求次小树的思路有点像,但是次小树可以再这个上面进行dp优化,其实这个题目也可以直接判断次小树是否等于最小树。好像有点说多了。

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N 110

using namespace std;

typedef struct

{

   int x ,y ,c;

}EDGE;

EDGE edge[N*N];

int  mer[N] ,mst[N];

int finds(int x)

{

   return x == mer[x] ? x : mer[x] = finds(mer[x]);

}

bool camp(EDGE a ,EDGE b)

{

   return a.c < b.c;

}

int MST(int n ,int m ,int co)

{

   for(int i = 1 ;i <= n ;i ++)mer[i] = i;

   int Ans = 0 ,sum = 0;

   for(int i = 1 ;i <= m ;i ++)

   {

      if(i == co) continue;

      int xx = finds(edge[i].x);

      int yy = finds(edge[i].y);

      if(xx != yy) 

      {

         Ans += edge[i].c ,sum ++ ;

         mer[xx] = yy;

         if(co == -1) mst[sum] = i;

      }

      if(sum == n - 1) break;

   }

   return Ans;



   

int main ()

{

   int t ,i ,n ,m;

   scanf("%d" ,&t);

   while(t--)

   {

      scanf("%d %d" ,&n ,&m);

      for(i = 1 ;i <= m ;i ++)

      scanf("%d %d %d" ,&edge[i].x ,&edge[i].y ,&edge[i].c);

      sort(edge + 1 ,edge + m + 1 ,camp);

      int Ans = MST(n ,m ,-1);

      for(i = 1 ;i < n ;i ++)

      {

         int tmp = MST(n ,m ,mst[i]);

         if(Ans == tmp) break;

      }

      i == n || m == n - 1? printf("%d\n" ,Ans) : puts("Not Unique!");

   }

   return 0;

}

      

     

      

      

      

   

#include<stdio.h>

#include<string.h>

#include<algorithm>

#define N 110

using namespace std;

typedef struct

{

   int x ,y ,c;

}EDGE;

typedef struct

{

   int to ,next;

}STAR;

EDGE edge[N*N];

STAR E[N*N];

int  map[N][N] ,mer[N] ,mark[N];

int list[N] ,tot ,mst[N];

int L[N] ,R[N] ,ll ,rr;

void add(int a, int b)

{

   E[++tot].to = b;

   E[tot].next = list[a];

   list[a] = tot;

}

int finds(int x)

{

   return x == mer[x] ? x : mer[x] = finds(mer[x]);

}

int minn(int x ,int y)

{

   return x < y ? x : y;

}

bool camp(EDGE a ,EDGE b)

{

   return a.c < b.c;

}

int MST(int n ,int m)

{

   for(int i = 1 ;i <= n ;i ++) mer[i] = i;

   int Ans = 0 ,sum = 0;

   memset(list ,0 ,sizeof(list)) ,tot = 1;

   for(int i = 1 ;i <= m ;i ++)

   {

      int xx = finds(edge[i].x);

      int yy = finds(edge[i].y);

      if(xx != yy) 

      {

         Ans += edge[i].c ,sum ++;

         mer[xx] = yy;

         mst[sum] = i;

         add(edge[i].x ,edge[i].y);

         add(edge[i].y ,edge[i].x);

      }

      if(sum == n - 1) break;

   }

   return Ans;

}

void DFS1(int x)

{

   for(int k = list[x] ;k ;k = E[k].next)

   {

      int to = E[k].to;

      if(mark[to]) continue;

      mark[to] = 1;

      L[++ll] = to;

      DFS1(to);

   }

}

void DFS2(int x)

{

   for(int k = list[x] ;k ;k = E[k].next)

   {

      int to = E[k].to;

      if(mark[to]) continue;

      mark[to] = 1;

      R[++rr] = to;

      DFS2(to);

   }

}

int main ()

{

   int t ,n ,m ,i ,j ,mk;

   scanf("%d" ,&t);

   while(t--)

   {

       scanf("%d %d" ,&n ,&m);

       for(i = 1 ;i <= n ;i ++)

       for(j = 1 ;j <= n ;j ++)

       map[i][j] = 100000000;

       for(i = 1 ;i <= m ;i ++)

       {

          scanf("%d %d %d" ,&edge[i].x ,&edge[i].y ,&edge[i].c); 

          int x = edge[i].x ,y = edge[i].y;

          map[x][y] = map[y][x] = minn(map[x][y] ,edge[i].c);

      }

      sort(edge + 1 ,edge + m + 1 ,camp);

      int Ans = MST(n ,m);

      if(m == n - 1)

      {

         printf("%d\n" ,Ans);

         continue;

      }

      mk = 0;

      for(i = 1 ;i < n && !mk;i ++)

      {

         memset(mark ,0 ,sizeof(mark));

         int l = edge[mst[i]].x ,r = edge[mst[i]].y;

         mark[l] = mark[r] = 1;

         ll = rr = 0;

         L[++ll] = l ,R[++rr] = r;    

         DFS1(l) ,DFS2(r);

         for(int j = 1 ;j <= ll && !mk;j ++)

         {

            for(int k = 1 ;k <= rr && !mk ;k ++)

            {

               if(L[j] == edge[mst[i]].x && R[k] == edge[mst[i]].y || L[j] == edge[mst[i]].y && R[k] == edge[mst[i]].x)

               continue;

               if(map[L[j]][R[k]] == edge[mst[i]].c) mk = 1;

            }

         }

      }

      mk ? printf("Not Unique!\n"): printf("%d\n" ,Ans);

   }

   return 0;

}

         

      

   

   

   

   

   

   

   

   

   

   

 

   

POJ1679判断最小生成树的唯一性的更多相关文章

  1. poj1679(判断最小生成树是否唯一)

    题意:给出n个点,m条边,要你判断最小生成树是否唯一. 思路:先做一次最小生成树操作,标记选择了的边,然后枚举已经被标记了的边,判断剩下的边组成的最小生成树是否与前面的相等,相等,则不唯一,否则唯一. ...

  2. POJ-1679 The Unique MST (判断最小生成树的唯一性)

    <题目链接> 题目大意: 给定一张无向图,判断其最小生成树是否唯一. 解题分析: 对图中每条边,扫描其它边,如果存在相同权值的边,则标记该边:用kruskal求出MST. 如果MST中无标 ...

  3. POJ1679 The Unique MST(Kruskal)(最小生成树的唯一性)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27141   Accepted: 9712 D ...

  4. POJ-1679 The Unique MST(次小生成树、判断最小生成树是否唯一)

    http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its minimum s ...

  5. PTA 7-4 最小生成树的唯一性 (35分)

    PTA 7-4 最小生成树的唯一性 (35分) 给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一.本题就要求你计算最小生成树的总权重,并且判断其是否唯一. 输入格式: ...

  6. poj1679(最小生成树)

    传送门:The Unique MST 题意:判断最小生成树是否唯一. 分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一. ...

  7. POJ 1679 The Unique MST(判断最小生成树是否唯一)

    题目链接: http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its min ...

  8. POJ 1679 The Unique MST (次小生成树 判断最小生成树是否唯一)

    题目链接 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. De ...

  9. K - The Unique MST (最小生成树的唯一性)

    Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...

随机推荐

  1. CVE-2019-11043-Nginx PHP 远程代码执行

    漏洞原因 Nginx 上 fastcgi_split_path_info 在处理带有 %0a 的请求时,会因为遇到换行符 \n 导致 PATH_INFO 为空.而 php-fpm 在处理 PATH_I ...

  2. 如何在Bash脚本中引入alias

    更多精彩内容,请关注微信公众号:后端技术小屋 alias的使用 在日常开发中,为了提高运维效率,我们会用alias(命令别名)来定义命令的简称.比如在~/.bash_profile中添加: alias ...

  3. 修改 Hosts 解决 Github 访问缓慢问题

    背景 最近访问 Github 经常出现访问速度慢的问题,甚至会出现无法连接的情况.有一天,在一次家常聊天中提到了这个事情,有一位热心的 Gitee 朋友就说:你改一下 Hosts 文件就可以了.修改了 ...

  4. HTML的基础语法

    区别于c语言这类高级语言,HTML不是编程语言,而好似一种描述型语言,用于描述网页中内容的显示方式. HTML标记以<>来进行标记.HTML中的标记按其是否成对出现,可以分为单标记和双标记 ...

  5. springboot源码解析-管中窥豹系列之BeanDefine如何加载(十三)

    一.前言 Springboot源码解析是一件大工程,逐行逐句的去研究代码,会很枯燥,也不容易坚持下去. 我们不追求大而全,而是试着每次去研究一个小知识点,最终聚沙成塔,这就是我们的springboot ...

  6. CQGUI框架之阴影圆角窗口实现

    CQGUI框架之阴影圆角窗口实现 大家好,我是IT文艺男,来自一线大厂的一线程序员 今天给大家讲解基于C++/Qt的CQGUI框架的阴影圆角窗口实现,实现效果如下图所示:: CQGUI开发环境:: M ...

  7. JAVA题目:正整数n若是其平方数的尾部,则称n为同构数 如:5*5=25, 25*25=625 问: 求1~99中的所有同构数

    1 /*题目:正整数n若是其平方数的尾部,则称n为同构数 2 如:5*5=25, 25*25=625 3 问: 求1~99中的所有同构数 4 */ 5 //分析:将1-99分为1-9和10-99,用取 ...

  8. 201871030125-王芬 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    实验三 软件工程结对项目 项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/xbsf/2018CST 这个作业要求链接 https://www.cnblogs ...

  9. sql 如何删除(代替)字段内某一部分内容

    方法一(此方法既可用于删除某一列字段中的某部分字符,也可用于替换某一列字段中的某部分字符) update Table_Name set Column_Name=replace(Column_Name, ...

  10. dubbo支持哪些通信协议?支持哪些序列化协议?

    (1)dubbo支持不同的通信协议 1)dubbo协议 dubbo://192.168.0.1:20188 默认就是走dubbo协议的,单一长连接,NIO异步通信,基于hessian作为序列化协议 适 ...