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 ...
随机推荐
- Kubernetes 实战 —— 02. 开始使用 Kubernetes 和 Docker
创建.运行及共享容器镜像 P23 运行容器 P24 运行 P24 可以运行 Docker 客户端可执行文件来执行各种 Docker 命令.例如:可以试着从 Docker Hub 的公共镜像仓库拉取.运 ...
- kali msf6 更新及bug处理
问题描述 Metasploit 漏洞库更新,利用msfupdate命令更新,出现已停止该命令更新,出现如下提示: 利用一句话安装更新,命令如下,安装过程中有部分警告出现 curl https://ra ...
- 推荐!!! Markdown图标索引网站
作者:三十三重天 博客: http://www.zhouhuibo.club 我们在观察别人的文章时候时,总能看到很多有趣的图标,像是这样
- key解析
密钥在不同实体之间传递,因此密钥必须可以序列化. 所有密钥三个特性: 算法:密钥使用的算法,如DES和DSA等,通过getAlgorithm()获取算法名 编码形式:密钥的外部编码形式,如X.509, ...
- Java关于整型类缓存[-128,127]之间的数字
我们在学习Java的包装类Integer.Long的时候可能会遇到这个问题: ①Integer a = 500;// Integer a = Integer.valueOf(500); 等价于上面的 ...
- 【安全研究】Domain fronting域名前置网络攻击技术
出品|MS08067实验室(www.ms08067.com) 千里百科 Domain Fronting基于HTTPS通用规避技术,也被称为域前端网络攻击技术.这是一种用来隐藏Metasploit,Co ...
- [题解] T'ill It's Over
前言 线段树+网络最大流的建模题. 博客园食用更佳 题目大意 最初时有 \(n\) 个 \(1\) .给定 \(op\) . \(l\) ,其中, \(l\) 为操作次数上限.你有四个操作: 若 \( ...
- OxyPlot.SkiaSharp显示中文乱码的问题
oxyplot 图表控件功能强大,使用很广泛.最近考虑到性能使用OxyPlot.SkiaSharp替代OxyPlot.WPF,曲线图表初步测试,性能提升近10倍左右.基于SkiaSharp图形引擎的一 ...
- 第一个真正的 GUI 程序——Tkinter教程系列02
第一个真正的 GUI 程序--Tkinter教程系列02 前言 欢迎光临我的个人博客 chens.life Tk 系列教程: Tkinter教程系列01--引言和安装Tk 我们将编写一个英尺和米的转换 ...
- 二、python学习-函数
类型判断 1.type()直接获取类型 2.isinstance 用法一:isinstance(值,类型) 返回真或假 用法二:isinstance(值,(类型1,类型2 ...)) 有一个类型满足 ...