题目大意:

给定一个无向图,寻找它的最小生成树,如果仅有一种最小生成树,输出所有边的和,否则输出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. JD商家后台管理的细节

    1: 宝贝主图和滚动图都是800px,只有刚好这么多时才能得到显示,否则不会显示. 2:宝贝描述图只支持750px, 只有这么多时才能得到显示, 刚开始不知道, 上传图片上去后, 发现始终无法显示, ...

  2. 018 [工具软件]截图贴图注释 Snipaste

    Snipaste 是一个截图贴图工具,绿色免费.官方主页:https://zh.snipaste.com/. 三大功能: 1.截图,可以自动识别窗口的各元素,可以精准到像素调整截图区域大小. 2.贴图 ...

  3. ASP.NET URLRewriter重写

    URLRewriter重写是微软官方出的第三方重写插件 下载地址:http://download.csdn.net/detail/ysn1314/5421587 下载后在项目中添加引用,然后再配置文件 ...

  4. js内置对象总结

    在js里,一切皆为或者皆可以被用作对象.可通过new一个对象或者直接以字面量形式创建变量(如var i="aaa"),所有变量都有对象的性质. 注意:通过字面量创建的对象在调用属性 ...

  5. python itertools模块实现排列组合

    转自:https://blog.csdn.net/specter11235/article/details/71189486 一.笛卡尔积:itertools.product(*iterables[, ...

  6. Fresco 源码分析(序)

    1. 为什么要写这个分析的博客 其实关于Fresco的相关内容,大家上网搜索,一般可以找到一大推,但是为什么我还要写关于这个的呢,因为在网上搜索中文和英文的关于fresco的相关知识时,大家只是潜在的 ...

  7. window下phpstudy开启redis扩展

    注:一定要注意自己PHP的版本结构是64还是32位的!其次查看PHP Extension Build是NTS or TS! 1.使用phpinfo()函数查看PHP的版本信息,这会决定扩展文件版本(特 ...

  8. ASP.NET Eval四种绑定方式 及详解

    1.1.x中的数据绑定语法 <asp:Literal id="litEval2" runat="server" Text='<%#DataBinde ...

  9. Bash Template

    #/bin/bash #set -x set -e usage() { cat <<EOF Usage: `basename $` [OPTIONS] <non-option arg ...

  10. JavaSE-10 多态

    学习要点 多态的优势和应用场合 父类和子类之间的类型转换 instanceof运算符的使用 父类作为方法形参实现多态 父类作为返回值实现多态 使用多态的原因 需求描述: 在宠物管理系统中,宠物饿了,需 ...