POJ1679判断最小生成树的唯一性
题意:
判断最小树是否唯一。
思路:
我用了两种方法,主要就是好久没敲了,找个水题练练手,第一种就是先一遍最小生成树,然后枚举最小生成树上的每一条边,然后取消这条边,在跑一遍最小生成树,就这样一直跑最小生成树,如果找到了一颗和之前的那个一样的,那么就是不唯一,第二种方法也是先最小树,然后枚举,在枚举的时候不是继续重新跑,而是断开当前边,把树分成两个集合<两次深搜实现>,然后在枚举这连个集合之间是否可以找到一个可以代替当前枚举的最小树的边,实现复杂度的话应该是第二种快点,但理论上也快不多少,只是为了练练手,在多说一句,第二种方法和求次小树的思路有点像,但是次小树可以再这个上面进行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判断最小生成树的唯一性相关推荐
- 判断最小生成树是否唯一
题目链接 题目描述:给一个图,判断最小生成树是否唯一,n<=100 解题思路:题意简单明了,最小生成树模板都会敲,网上也没有什么特别好的方法,都是最简单暴力枚举,枚举的前提,有可以取代它的边. ...
- poj 1679 判断最小生成树是否唯一
/* 只需判断等效边和必选边的个数和n-1的关系即可 */ #include<stdio.h> #include<stdlib.h> #define N 110 struct ...
- PAT顶级 1016 Uniqueness of MST (35分)(判断最小生成树是否唯一)
添加链接描述 Given any weighted undirected graph, there exists at least one minimum spanning tree (MST) if ...
- hdu4975 行列和构造矩阵(dp判断唯一性)
题意: 和hdu4888一样,只不过是数据加强了,就是给你行列的和,让你构造一个矩阵,然后判断矩阵是否唯一. 思路: 构造矩阵很简单,跑一次最大流就行了,关键是判断矩阵的唯一性 ...
- 怎样从PHP文件中提取特征码,关于判断文件唯一性,怎么提取特征码
关于判断文件唯一性,怎么提取特征码 Delphi / Windows SDK/API http://www.delphi2007.net/DelphiAPI/html/delphi_200611081 ...
- 最小生成树(kruskal、prim、最小生成森林问题、严格次小生成树)
整理的算法模板合集: ACM模板 目录 一.kruskal算法 二.prim算法 三.Boruvka算法 四.生成森林问题(K颗树) 五.最小生成树的唯一性 六.严格次小生成树 LCA优化的次小生成树 ...
- poj1679(次小生成树)
题意:判断最小生成树是否唯一,如果唯一则是输出最小长度:否则输出 Not Unique! 其中:枚举每条不在最小生成树上的边,并把这条边放到最小生成树上面,然后就一定形成环,那么我们将这条环中取出最长 ...
- hdu4915 判断括号匹配
题意: 问你括号匹配是否唯一,三种字符'(','?',')',问号可以变成任何字符. 思路: 首先我们要学会判断当前串是否成立?怎么判断?我的方法是跑两遍,开三个变变量 s1 ...
- 五个运动员参加比赛根据他们说的话判断结果
#define _CRT_SECURE_NO_WARNINGS 1 //题目要求:5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果 //A选手说:B第二,我第三: //B选手说:我第二,E第四 ...
最新文章
- GCC 链接 xxx:No such file or directory 及运行可执行文件 error while loading shared libraries: xxx.so 解决方案
- mysql5.7.20安装红黑_Window环境安装MySQLServer5.7.21
- 渗透测试报告甲乙概述
- leetcode184. 部门工资最高的员工(SQL) 连接+嵌套查询
- Android 系统(156)----Android APP适配全面屏手机的技术要点
- hadoop 集群间数据迁移
- hdu4576(概率DP)
- 关于ODBC使用SQL语句和调用存储过程传递参数的使用方式说明
- 使用Ant构建简单项目
- 鼠标键盘录制工具 脚本录制器 游戏脚本录制工具
- 【文献研究】国际班轮航运的合作博弈:The coopetition game in international liner shipping
- LED背光源是什么,背光源LED是什么意思呢?
- 盘点:54款真正耐玩的独立游戏
- 两种方法实现奇数和偶数的和(Java)
- 第一篇博客-Sql排名函数DENSE_RANK
- Ravpower苹果20W充电器,充电快又稳,使用更安全
- 【小白学OpenCV】(零)——计算机图像基础
- 【CSS3】变形--位移 translate()
- oracle倒库脚本
- IDEA设置字体随鼠标滑动改变大小
热门文章
- Android 网络连接状态的监控
- PInvoke复习之深入理解char*与wchar_t*与string以及wstring之间的相互转换
- EF架构~在global.asax里写了一个异常跳转,不错!
- 匿名对象和object的转换
- 离散数学及其应用第6版中文版勘误
- 服务器数据恢复难题--操作系统恢复的方法和思路
- benet 3.0的构建企业网络视频第二章地址
- openstack搭建之-neutron配置(11)
- IntelliTest(5) - The IntelliTest Reference Manual[译]
- Python打包工具setuptools的使用