The Unique MST

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 36692   Accepted: 13368

Description

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

Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the following properties: 
1. V' = V. 
2. T is connected and acyclic.

Definition 2 (Minimum Spanning Tree): Consider an edge-weighted, connected, undirected graph G = (V, E). The minimum spanning tree T = (V, E') of G is the spanning tree that has the smallest total cost. The total cost of T means the sum of the weights on all the edges in E'.

Input

The first line contains a single integer t (1 <= t <= 20), the number of test cases. Each case represents a graph. It begins with a line containing two integers n and m (1 <= n <= 100), the number of nodes and edges. Each of the following m lines contains a triple (xi, yi, wi), indicating that xi and yi are connected by an edge with weight = wi. For any two nodes, there is at most one edge connecting them.

Output

For each input, if the MST is unique, print the total cost of it, or otherwise print the string 'Not Unique!'.

Sample Input

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 Output

3
Not Unique! 题解:
次小生成树,维护一个两点间的最小距离,最后再向上加
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
#define line cout<<"------------------"<<endl;
const int MAXN=1e4+10;
const int INF=0x3f3f3f3f;
int n,m;
struct node{
int x,y;
int v;
bool vis;
}Edge[MAXN];
bool cmp(node a,node b)
{
return a.v<b.v;
}
int pre[MAXN];
int Find(int a)
{
if(pre[a]==a)
return a;
return Find(pre[a]);
}
vector<int >G[110]; int maxd[110][110];//并查集划到一个树上后,树上任意两点之间的距离 void init()
{
for (int i = 1; i <=n; ++i) {
G[i].clear();
pre[i] = i;
G[i].push_back(i);
} }
int main()
{
int _;
scanf("%d",&_);
while(_--)
{
scanf("%d%d",&n,&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&Edge[i].x,&Edge[i].y,&Edge[i].v);
Edge[i].vis=false;
}
sort(Edge+1,Edge+1+m,cmp);
int sum=0;
for (int i = 1; i <=m ; ++i) {
int x=Find(Edge[i].x);
int y=Find(Edge[i].y);
if(x!=y)
{
pre[x]=y;
sum+=Edge[i].v;
int len1=G[x].size();
int len2=G[y].size();
for (int j = 0; j <len1 ; ++j) {
for (int k = 0; k <len2 ; ++k) {
maxd[G[x][j]][G[y][k]]=maxd[G[y][k]][G[x][j]]=Edge[i].v;//构建两点间最小距离
}
}
int tem[110];
for (int j = 0; j <len2 ; ++j) {
tem[j]=G[y][j];
}
for (int j = 0; j <len1 ; ++j) {
G[y].push_back(G[x][j]);
}
for (int j = 0; j <len2 ; ++j) {
G[x].push_back(tem[j]);
}
Edge[i].vis=true;
}
}
int cis=INF;
for (int i = 1; i <=m ; ++i) {//从不是最小生成树上的边,遍历向上加。找到次小生成树
if(!Edge[i].vis)
cis=min(cis,sum+Edge[i].v-maxd[Edge[i].x][Edge[i].y]);
}
if(cis>sum)
printf("%d\n",sum);
else
printf("Not Unique!\n");
} return 0;
}
//poj1679

  

POJ1679(次小生成树)的更多相关文章

  1. POJ1679(次小生成树)

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

  2. poj1679次小生成树入门题

    次小生成树求法:例如求最小生成树用到了 1.2.4这三条边,总共5条边,那循环3次的时候,每次分别不用1.2.4求得最小生成树的MST,最小的MST即为次小生成树 如下代码maxx即求最小生成树时求得 ...

  3. poj1679 次小生成树

    prim方法:先求过一遍prim,同时标记使用过得边.然后同时记录任意2点间的最大值. 每次加入一条新的边,会产生环,删去环中的最大值即可. #include<stdio.h> #incl ...

  4. POJ1679 The Unique MST[次小生成树]

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28673   Accepted: 10239 ...

  5. 次小生成树(POJ1679/CDOJ1959)

    POJ1679 首先求出最小生成树,记录权值之和为MinST.然后枚举添加边(u,v),加上后必形成一个环,找到环上非(u,v)边的权值最大的边,把它删除,计算当前生成树的权值之和,取所有枚举加边后生 ...

  6. POJ1679 The Unique MST【次小生成树】

    题意: 判断最小生成树是否唯一. 思路: 首先求出最小生成树,记录现在这个最小生成树上所有的边,然后通过取消其中一条边,找到这两点上其他的边形成一棵新的生成树,求其权值,通过枚举所有可能,通过这些权值 ...

  7. POJ1679 The Unique MST 【次小生成树】

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

  8. 次小生成树(poj1679)

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

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

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

随机推荐

  1. ORACLE_TRIGGER

    PL/SQL TRIGGER Statement PL/SQL TRIGGER  Statement The trigger statemet is a especially stored proce ...

  2. 读REDIS数据结构

    一.DICT 主要有两个问题: 1.散列冲突,解决办法是拉链法 typedef struct dictEntry { void *key; union { void *val; uint64_t u6 ...

  3. bzoj5029 贴小广告

    Description 现在有一堵墙,墙上分为若干个单元.接下来会来n个人在墙上贴小广告.每次每个人选择墙上连续一段的单元贴上自己公司与众不同的小广告.因为小广告可能会出现被覆盖的情况,由于公司之间存 ...

  4. 【[SDOI2014]旅行】

    听说这是动态开点主席树的板子题,但是发现我还不会,于是就来写一写 其实跟主席树一个样子的 这里就是存个板子吧 #include<cstdio> #include<cstring> ...

  5. 【转】JS模块化工具requirejs教程(二):基本知识

    前一篇:JS模块化工具requirejs教程(一):初识requirejs 我们以非常简单的方式引入了requirejs,这一篇将讲述一下requirejs中的一些基本知识,包括API使用方式等. 基 ...

  6. Linux云主机 监控方案浅析

    1.为何需要监控 监控是运维工程师的眼睛,它可帮助运维工程师第一时间发现系统的问题. 对于服务器的整个生命周期,都要和监控打交道: 当有服务器上架,都需要加入比如CPU负载.内存.网络.磁盘等基础监控 ...

  7. Android学习笔记_5_文件操作

    1.Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的. package com.example.servi ...

  8. 用java语言编写的简单二叉树

    package com.cjonline.foundation.evisa; public class TestTree { private int data=-1; private TestTree ...

  9. 轻量ORM-SqlRepoEx (一)SqlRepoEx介绍

    一.SqlRepo项目 发现SqlRepo项目库是在构建自动代码工具时.对于数据访问,在.Net下,有很多选择,比如EF,但EF使用起来,不是很方便的.以前一直使用Atk.Expression库+Sy ...

  10. C#中Math.Round()的中国式用法

    C#中的Math.Round()并不是使用的"四舍五入"法.而是(银行家算法),即:四舍六入五取偶.事实上这也是IEEE的规范,因此所有符合IEEE标准的语言都应该采用这样的算法. ...