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判断最小生成树的唯一性的更多相关文章
- poj1679(判断最小生成树是否唯一)
题意:给出n个点,m条边,要你判断最小生成树是否唯一. 思路:先做一次最小生成树操作,标记选择了的边,然后枚举已经被标记了的边,判断剩下的边组成的最小生成树是否与前面的相等,相等,则不唯一,否则唯一. ...
- POJ-1679 The Unique MST (判断最小生成树的唯一性)
<题目链接> 题目大意: 给定一张无向图,判断其最小生成树是否唯一. 解题分析: 对图中每条边,扫描其它边,如果存在相同权值的边,则标记该边:用kruskal求出MST. 如果MST中无标 ...
- POJ1679 The Unique MST(Kruskal)(最小生成树的唯一性)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27141 Accepted: 9712 D ...
- POJ-1679 The Unique MST(次小生成树、判断最小生成树是否唯一)
http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its minimum s ...
- PTA 7-4 最小生成树的唯一性 (35分)
PTA 7-4 最小生成树的唯一性 (35分) 给定一个带权无向图,如果是连通图,则至少存在一棵最小生成树,有时最小生成树并不唯一.本题就要求你计算最小生成树的总权重,并且判断其是否唯一. 输入格式: ...
- poj1679(最小生成树)
传送门:The Unique MST 题意:判断最小生成树是否唯一. 分析:先求出原图的最小生成树,然后枚举删掉最小生成树的边,重做kruskal,看新的值和原值是否一样,一样的话最小生成树不唯一. ...
- POJ 1679 The Unique MST(判断最小生成树是否唯一)
题目链接: http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its min ...
- POJ 1679 The Unique MST (次小生成树 判断最小生成树是否唯一)
题目链接 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. De ...
- K - The Unique MST (最小生成树的唯一性)
Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...
随机推荐
- PTA甲级—常用技巧与算法
散列 1078 Hashing (25 分) Quadratic probing (with positive increments only) is used to solve the collis ...
- ASP.NET Core扩展库
亲爱的.Neter们,在我们日复一日的编码过程中是不是会遇到一些让人烦恼的事情: 日志配置太过复杂,各种模板.参数也搞不清楚,每次都要去查看日志库的文档,还需要复制粘贴一些重复代码,好无赖 当需要类型 ...
- vs - 调试的技巧
在自助和局部变量窗口中固定属性 https://docs.microsoft.com/zh-cn/visualstudio/debugger/autos-and-locals-windows?view ...
- WPF 基础 - MultiBinding
MultiBinding 与 Binding 一样继承自 BindingBase,因此可以使用 Binding 的地方都可以使用 MultiBinding. namespace System.Wind ...
- python模块的打包和安装
假设需要打包的模块文件名是mm.py,代码如下: a = 2 在mm.py文件的同目录下新建一个setup.py文件,代码如下: from distutils.core import setup se ...
- IPFS矿池集群方案详解
IPFS作为一项分布式存储技术,可以说是web3.0发展的基石.关于IPFS的产业,如存储.技术.矿机.矿池等也发展得非常迅速. 什么是单机挖矿? 单机挖矿就是一台机器就是一个节点,一台机器就完成挖矿 ...
- JSP实验报告
- 翻译:《实用的Python编程》06_03_Producers_consumers
目录 | 上一节 (6.2 自定义迭代) | 下一节 (6.4 生成器表达式) 6.3 生产者,消费者和管道 生成器在设置各种生产者/消费者问题(producer/consumer problems) ...
- AggregateReport V2.2.0
1. 说明 AggregateReport V2.2.0终于跟大家见面了!从V1.0.0到V2.2.0 宝路听取了很多同学的建议!感谢大家一路的信任与支持! 2. 文章导读 如果不了解此工具的同学,建 ...
- 提高Python的性能
01 使用哈希表的数据结构 如果在程序中遇到大量搜索操作时,并且数据中没有重复项,则可以使用查找而不是循环.举例如下: items = ['a', 'b',..,'100m'] #1000s of ...