题目大意:

给定一个无向图,寻找它的最小生成树,如果仅有一种最小生成树,输出所有边的和,否则输出unique!

根据kruscal原理来说,每次不断取尽可能小的边不断添加入最小生成树中,那么可知如果所有边的长度都不相同,那么kruscal取得过程必然只有一种情况,由小到大

所以要是存在多种情况的最小生成树,那么必然是存在相同的边

初始将所有相同的边进行标记,生成第一次最小生成树后,不断去除其中带标记的边,然后再计算最小生成树,判断能否得到同样的答案,如果可以,说明不止一种情况

 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 105
int fa[N] , same[N] , first[N] , k;
int rec[N] , amo;//rec[]记录MST中含有相同长度边的位置,amo记录其数量
struct Edge{
int x,y,d,next,flag;
bool same;
bool operator<(const Edge &m) const{
return d<m.d;
}
}e[N*N]; int find_head(int x)
{
while(fa[x]!=x) x=fa[x];
return x;
} bool Union(int x,int y)
{
int fa_x = find_head(x);
int fa_y = find_head(y);
fa[fa_x] = fa_y;
return fa_x == fa_y;
} void add_edge(int x, int y , int d)
{
e[k].x=x , e[k].y=y , e[k].d=d , e[k].flag= , e[k].next=first[x];
e[k].same = false;
first[x] = k++;
} int cal_MST(int n , int flag)
{
int ans = , cnt=;
for(int i= ; i<=n ; i++) fa[i]=i;
for(int i= ; i<k ; i++){
if(e[i].flag==){
if(!Union(e[i].x , e[i].y)){
ans+=e[i].d;
if(e[i].same && flag){
rec[amo++] = i;
}
cnt++;
if(cnt == n-) break;
}
}
}
return ans;
} int main()
{
int T;
scanf("%d" , &T);
while(T--)
{
int n , m , x , y , d;
scanf("%d%d" , &n , &m);
k=;
memset(first , - , sizeof(first));
for(int i= ; i<m ; i++){
scanf("%d%d%d" , &x , &y , &d);
add_edge(x , y , d);
} sort(e , e+k);
//对存在相同边的边进行标记
for(int i= ; i<k ; i++)
if(e[i].d == e[i-].d) e[i].same=e[i-].same=true;
amo = ;
int ans = cal_MST(n , );
bool is_unique = true;
for(int i= ; i<amo ; i++){
e[rec[i]].flag = ;
int t=cal_MST(n , );
if(t == ans){
is_unique=false;
break;
}
e[rec[i]].flag = ;
}
if(is_unique) printf("%d\n" , ans);
else puts("Not Unique!");
}
return ;
}

上面那个明显复杂度比较高

我们可以求解出次小生成树的值与最小生成树的值进行比较判断是否唯一

先求出最小生成树,用二维数组mx[][]记录最小生成树上两个点之间路径上最长边的长度

然后找到每一条不属于最小生成树的边u,v ,这样可以与原最小生成树中u->v的路径形成一个环,那么最后需要在环中删去一条最长边,那么只要不断得到这个差值的最小值

用最小生成树的值减去他就可以了

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define N 105
const int INF = 0x3f3f3f3f;
int mx[N][N] , w[N][N];
int n , m;
int d[N] , connect[N];
bool vis[N][N] , in[N]; int prim()
{
int ret = ;
memset(vis , , sizeof(vis));
memset(connect , , sizeof(connect));
memset(in , , sizeof(in));
memset(mx , , sizeof(mx));
d[] = INF , in[] = true;
for(int i= ; i<=n ; i++)
if(w[][i]>=){
d[i] = w[][i];
connect[i] = ;
}
else d[i] = INF; for(int i= ; i<n ; i++){
int minn = INF , index = ;
for(int j= ; j<=n ; j++){
if(in[j]) continue;
if(d[j]<minn) minn=d[j] , index=j;
}
int u = connect[index];
d[index] = INF , vis[index][u] = vis[u][index] = true;
mx[index][u] = mx[u][index] = minn , in[index] = true , ret+=minn;
for(int j= ; j<=n ; j++){
if(in[j] || w[index][j]<) continue;
if(w[index][j]<d[j]) d[j] = w[index][j] , connect[j] = index;
}
for(int j= ; j<=n ; j++){
if(!in[j]) continue;
mx[j][index] = mx[index][j] = max(mx[index][j] , max(mx[index][u] , minn));
}
}
return ret;
} int sec_mst(int mst)
{
int del = INF;
for(int i= ; i<=n ; i++){
for(int j=i+ ; j<=n ; j++){
if(!vis[i][j] && w[i][j]>=){
del = min(del , mx[i][j]-w[i][j]);
}
}
}
return mst-del;
} int main()
{
// freopen("in.txt" , "r" , stdin);
int T;
scanf("%d" , &T);
while(T--)
{
scanf("%d%d" , &n , &m);
memset(w , - , sizeof(w));
int u , v , wei;
while(m--){
scanf("%d%d%d" , &u , &v , &wei);
w[u][v] = w[v][u] = wei;
}
int ret = prim();
int sec = sec_mst(ret);
if(ret == sec) puts("Not Unique!");
else printf("%d\n" , ret);
}
return ;
}

POJ 1679 判最小生成树的不唯一性 或 利用次小生成树求解的更多相关文章

  1. poj 1679 判断最小生成树是否唯一

    /* 只需判断等效边和必选边的个数和n-1的关系即可 */ #include<stdio.h> #include<stdlib.h> #define N 110 struct ...

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

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

  3. POJ 1679 The Unique MST (最小生成树)

    The Unique MST 题目链接: http://acm.hust.edu.cn/vjudge/contest/124434#problem/J Description Given a conn ...

  4. POJ 1679 The Unique MST(次小生成树)

    题意:求解最小生成树的权值是否唯一,即要我们求次小生成树的权值两种方法求最小生成树,一种用prim算法, 一种用kruskal算法 一:用prim算法 对于给定的图,我们可以证明,次小生成树可以由最小 ...

  5. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  6. 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  7. POJ 1679 The Unique 次最小生成树 MST

    http://poj.org/problem?id=1679 题目大意: 给你一些点,判断MST(最小生成树)是否唯一. 思路: 以前做过这题,不过写的是O(n^3)的,今天学了一招O(n^2)的,哈 ...

  8. (poj)1679 The Unique MST 求最小生成树是否唯一 (求次小生成树与最小生成树是否一样)

    Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...

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

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

随机推荐

  1. C# winform与Javascript的相互调用[转]

    原文链接<html> <head> <meta http-equiv="Content-Language" content="zh-cn&q ...

  2. mysqlshow(数据库对象查看工具)

    mysqlshow是mysql客户端对象查看工具,可以用来查看数据库.数据库中的表.表中的列.索引等. 1.mysqlshow命令的语法 shell > mysqlshow [options] ...

  3. D. Mahmoud and a Dictionary 种类并查集

    http://codeforces.com/contest/766/problem/D 所谓种类并查集,题型一般如下:给定一些基本信息给你,然后又给出一些信息,要求你判断是真是假.例如给出a和b支持不 ...

  4. 针对谷歌默认最小字体12px的正确解决方案

    利用css3的缩放,其最终大小就是:12px * 0.9(缩放比例) = 10.8px; 居然行得通.但回头一想,这么写的话,IE7 IE8会不会不兼容,还是12px呢?不出所料,果然不兼容.此时,又 ...

  5. POI导出时,将指定的列设置为下拉列表

    本示例设置第2列为下拉框(下拉框内容为:是/否),从第5行开始到5657行结束. 关键代码示例: ComboxList = new String[]{"是","否&quo ...

  6. js实现元素水平垂直居中

    之前有写过css/css3实现元素的水平和垂直居中的几种方法点我,但是css3属性不是所有浏览器都能兼容的,今天写下js实现未知宽高的元素的水平和垂直居中. <!DOCTYPE html> ...

  7. Ajax请求WebService跨域问题

    1.背景 用Jquery中Ajax方式在asp.net开发环境中WebService接口的调用 2.出现的问题 原因分析:浏览器同源策略的影响(即JavaScript或Cookie只能访问同域下的内容 ...

  8. AttributeError: 'dict' object has no attribute 'encode'

    首先这是一个很简单的 运行时错误: 错误分析: AttributeError:属性错误,造成这种错误的原因可能有: 你尝试访问一个不存在的属性或方法.检查一下拼写!你可以使用内建函数 dir 来列出存 ...

  9. VS2017 ATL创建ActiveX编程要点

    VS2017 ATL创建ActiveX控件编程要点: 一.创建vs项目需要安装器visual studio installer中: 安装 visual studio扩展开发中的 用于x86和x64的V ...

  10. Java之Servlet文件下载20190228

    jsp页面: <%@ page language="java" contentType="text/html; charset=utf-8" pageEn ...