判断MST是不是唯一的 如果是唯一的 就输出最小的权值和 如果不是唯一的 就输出Not Unique!

次小生成树就是第二小生成树  如果次小生成树的权值和MST相等  那么MST就不是唯一的

法一:

先求出最小的权值和 然后一条边一条边的删
先标记MST中所使用的边 删边就是屏蔽这条边后 再对剩下的边(不管这些边是否被标记)求MST 如果最后的权值和 与开始算出的最小的那个 相等 就说明不是唯一的

Sample Input

2 //T
3 3 //n m
1 2 1// u v w
2 3 2
3 1 3
4 4
1 2 2
2 3 2
3 4 2
4 1 2
Sample Output

3
Not Unique!

Kruskal

 # include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
# define LL long long
using namespace std ; int n ;
const int MAXN=;//最大点数
const int MAXM=;//最大边数
int F[MAXN];//并查集使用
int del[MAXM] ;
struct Edge
{
int u,v,w;
int tag ;
}edge[MAXM];//存储边的信息,包括起点/终点/权值 int tol;//边数,加边前赋值为0
void addedge(int u,int v,int w)
{ edge[tol].u=u;
edge[tol].v=v;
edge[tol].tag = ;
edge[tol++].w=w;
}
bool cmp(Edge a,Edge b)
{//排序函数,讲边按照权值从小到大排序
return a.w<b.w;
}
int find(int x)
{
if(F[x]==-)return x;
else return F[x]=find(F[x]);
}
int Kruskal(int d)//传入点数,返回最小生成树的权值,如果不连通返回-1
{
memset(F,-,sizeof(F)); int cnt=;//计算加入的边数
int ans=;
for(int i=;i<tol;i++)
{
if (i == d) //屏蔽id为d的这一条边
continue ;
int u=edge[i].u;
int v=edge[i].v;
int w=edge[i].w;
int t1=find(u);
int t2=find(v);
if(t1!=t2)
{
ans+=w;
F[t1]=t2;
cnt++;
edge[i].tag = ;
}
if(cnt==n-)break;
}
if(cnt<n-)return -;//不连通
else return ans;
} int main()
{ // freopen("in.txt","r",stdin) ;
int m ;
int T ;
scanf("%d" , &T) ;
while(T--)
{
scanf("%d %d" , &n , &m) ;
int i ;
int u , v , w ;
tol = ;
while(m--)
{
scanf("%d %d %d" , &u , &v , &w) ;
addedge(u , v , w) ;
} sort(edge,edge+tol,cmp);
int ans = Kruskal(-) ; int k = ;
for (i = ; i < tol ; i++)
{
if (edge[i].tag == )
{
del[k] = i ;
k++ ;
}
}
bool flag = ;
int t_ans ;
for (i = ; i < k ; i++)
{
t_ans = Kruskal(del[i]) ;
if (t_ans == ans)
{
flag = ;
break ;
}
}
if (flag)
printf("Not Unique!\n") ;
else
printf("%d\n" , ans) ; }
return ;
}

法二 : Prim

 /*
* 次小生成树
* 求最小生成树时,用数组Max[i][j]来表示MST中i到j最大边权
* 求完后,直接枚举所有不在MST中的边,替换掉最大边权的边,更新答案
* 点的编号从0开始
*/
# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
# define LL long long
using namespace std ; int n ;
const int MAXN=;
const int INF=0x3f3f3f3f;
bool vis[MAXN];
int lowc[MAXN];
int pre[MAXN];
int Max[MAXN][MAXN];//Max[i][j]表示在最小生成树中从i到j的路径中的最大边权
bool used[MAXN][MAXN];
int cost[MAXN][MAXN];
int Prim()
{
int ans=;
memset(vis,false,sizeof(vis));
memset(Max,,sizeof(Max));
memset(used,false,sizeof(used));
vis[]=true;
pre[]=-;
for(int i=;i<n;i++)
{
lowc[i]=cost[][i];
pre[i]=;
}
lowc[]=;
for(int i=;i<n;i++)
{
int minc=INF;
int p=-;
for(int j=;j<n;j++)
if(!vis[j]&&minc>lowc[j])
{
minc=lowc[j];
p=j;
}
if(minc==INF)return -;
ans+=minc;
vis[p]=true;
used[p][pre[p]]=used[pre[p]][p]=true;
for(int j=;j<n;j++)
{
if(vis[j])Max[j][p]=Max[p][j]=max(Max[j][pre[p]],lowc[p]);
if(!vis[j]&&lowc[j]>cost[p][j])
{
lowc[j]=cost[p][j];
pre[j]=p;
}
}
}
return ans;
} int smst(int ans)
{
int Min=INF;
for(int i=;i<n;i++)
for(int j=i+;j<n;j++)
if(cost[i][j]!=INF && !used[i][j])
{
Min=min(Min,ans+cost[i][j]-Max[i][j]);
}
if(Min==INF)return -;//不存在
return Min;
} int main()
{
// freopen("in.txt","r",stdin) ;
int T;
int m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
int u,v,w;
for(int i=;i<n;i++)
for(int j=;j<n;j++)
{
if(i==j)cost[i][j]=;
else cost[i][j]=INF;
}
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
u--;v--;
cost[u][v]=cost[v][u]=w;
}
int ans=Prim();
if(ans==-)
{
printf("Not Unique!\n");
continue;
}
if(ans==smst(ans))printf("Not Unique!\n");
else printf("%d\n",ans);
}
return ;
}

poj 1679 判断MST是不是唯一的 (次小生成树)的更多相关文章

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

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

  2. POJ 1679 判断最小树是否唯一

    题意:       给你一个图,问你最小树是否唯一,唯一则输出最小数的权值,不唯一输出Not Unique! 思路:      题目问的是最小树是否唯一,其实也就是在问次小树是否等于最小树,如果等于则 ...

  3. POJ 1679 The Unique MST (次小生成树)题解

    题意:构成MST是否唯一 思路: 问最小生成树是否唯一.我们可以先用Prim找到一棵最小生成树,然后保存好MST中任意两个点i到j的这条路径中的最大边的权值Max[i][j],如果我们能找到一条边满足 ...

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

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

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

    http://poj.org/problem?id=1679 Description Given a connected undirected graph, tell if its minimum s ...

  6. poj 1679 The Unique MST 【次小生成树+100的小数据量】

    题目地址:http://poj.org/problem?id=1679 2 3 3 1 2 1 2 3 2 3 1 3 4 4 1 2 2 2 3 2 3 4 2 4 1 2 Sample Outpu ...

  7. poj 1679 The Unique MST (次小生成树模板题)

    Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spann ...

  8. POJ1679 The Unique MST —— 次小生成树

    题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total S ...

  9. POJ1679The Unique MST(次小生成树)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 25203   Accepted: 8995 D ...

随机推荐

  1. Codeforces 590D Top Secret Task

    D. Top Secret Task time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  2. bzoj千题计划306:bzoj2342: [Shoi2011]双倍回文 (回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=2342 解法一: 对原串构建回文自动机 抽离fail树,从根开始dfs 设len[x]表示节点x表示 ...

  3. MyBatis下MySqL用户口令不能为空

    jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3308/testjdbc.username=testjdbc.pas ...

  4. 破解WPA工具Tkiptun-ng

    1.关于Tkiptun-ng 该工具能够将一些帧插入到使用WPA TKIP且开启Qos的无线网络中. 2.Tkiptun-ng原理 Tkiptun-ng设计思路主要是通过获得一个包含明文与MIC(消息 ...

  5. 属性动画QPropertyAnimation

    属性动画QPropertyAnimation 改变大小.颜色或位置是动画中的常见操作,而QPropertyAnimation类可以修改控件的属性值 大小改变动画: import sys from Py ...

  6. luogu P2508 [HAOI2008]圆上的整点

    传送门 推荐去bzoj看个视频了解一下 不要妄想视频直接告诉你题解 但是视频告诉了你后面要用的东西 首先我们要求的是\(x^2+y^2=n^2(x,y\in Z)\)的\((x,y)\)对数,可以转化 ...

  7. Python实现图片压缩

    项目中大量用到图片加载,由于图片太大,加载速度很忙,因此需要对文件进行统一压缩 一:导入包 from PIL import Image import os 二:获取图片文件的大小 def get_si ...

  8. k8s系列~docker mysql

    docker封装mysql的一些心得 简介:今天咱们来聊聊容器化mysql的一些心得 版本:Docker version 18.03 mysql 5.7.21考虑条件:  1 选好合适的docker镜 ...

  9. WPS 表格筛选两列相同数据-完美-2017年11月1日更新

    应用: 1.选出A列中的数据是否在B列中出现过: 2.筛选出某一批序号在一个表格里面的位置(整批找出) 3.其实还有其他很多应用,难描述出来... ... A列中有几百的名字,本人想帅选出B列中的名字 ...

  10. 如何调整cell的大小

    一般情况下,我们使用tableview的时候从来没有设置过cell的大小(w,h).位置(x,y)等,而是系统直接给我们自动生成,但是有的时候我们可能会改动cell的大小及位置,比如:在适配ios6跟 ...