题目链接:http://poj.org/problem?id=1679

题意:

  给你一个图,问你这个图的最小生成树是否唯一。

题解:

  求这个图的最小生成树和次小生成树。如果相等,则说明不唯一。

  次小生成树(倍增算法):

    maxn[k][i]:表示从节点i向上走2^k步,这一段中边权的最大值。

    枚举每一条不在MST中的边,求出这条边两端点之间在MST上路径上的最大边权mx。

    次小生成树(非严格) = max(MST - mx + len)

AC Code:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAX_N 105
#define MAX_E 10005
#define MAX_K 20
#define INF 1000000000 using namespace std; struct E
{
int s;
int t;
int len;
E(int _s,int _t,int _len)
{
s=_s;
t=_t;
len=_len;
}
E(){}
friend bool operator < (const E &a,const E &b)
{
return a.len<b.len;
}
}; struct Edge
{
int dest;
int len;
Edge(int _dest,int _len)
{
dest=_dest;
len=_len;
}
Edge(){}
}; int n,m,t;
int fa[MAX_N];
int dep[MAX_N];
int par[MAX_K][MAX_N];
int maxn[MAX_K][MAX_N];
bool vis[MAX_E];
vector<E> e;
vector<Edge> edge[MAX_N]; void read()
{
cin>>n>>m;
e.clear();
for(int i=;i<=n;i++)
{
edge[i].clear();
}
int a,b,v;
for(int i=;i<=m;i++)
{
cin>>a>>b>>v;
e.push_back(E(a,b,v));
}
} void init_union_find()
{
for(int i=;i<=n;i++)
{
fa[i]=i;
}
} int find(int x)
{
return fa[x]==x ? x : fa[x]=find(fa[x]);
} void unite(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py) return;
fa[px]=py;
} bool same(int x,int y)
{
return find(x)==find(y);
} int kruskal()
{
init_union_find();
sort(e.begin(),e.end());
memset(vis,false,sizeof(vis));
int cnt=;
int res=;
for(int i=;i<e.size() && cnt<n-;i++)
{
E temp=e[i];
if(!same(temp.s,temp.t))
{
cnt++;
res+=temp.len;
vis[i]=true;
unite(temp.s,temp.t);
edge[temp.s].push_back(Edge(temp.t,temp.len));
edge[temp.t].push_back(Edge(temp.s,temp.len));
}
}
return cnt==n- ? res : -;
} void dfs(int now,int p,int d,int l)
{
dep[now]=d;
par[][now]=p;
maxn[][now]=l;
for(int i=;i<edge[now].size();i++)
{
Edge temp=edge[now][i];
if(temp.dest!=p) dfs(temp.dest,now,d+,temp.len);
}
} void init_lca()
{
dfs(,-,,-);
for(int k=;k+<MAX_K;k++)
{
for(int i=;i<=n;i++)
{
if(par[k][i]==-)
{
par[k+][i]=-;
maxn[k+][i]=-;
}
else
{
par[k+][i]=par[k][par[k][i]];
maxn[k+][i]=max(maxn[k][i],maxn[k][par[k][i]]);
}
}
}
} int cal_max(int a,int b)
{
if(dep[a]>dep[b]) swap(a,b);
int res=-;
for(int k=;k<=MAX_K && dep[a]!=dep[b];k++)
{
if(((dep[b]-dep[a])>>k)&)
{
res=max(res,maxn[k][b]);
b=par[k][b];
}
}
if(a==b) return res;
for(int k=MAX_K-;k>=;k--)
{
if(par[k][a]!=par[k][b])
{
res=max(res,maxn[k][a]);
res=max(res,maxn[k][b]);
a=par[k][a];
b=par[k][b];
}
}
return max(res,maxn[][a]);
} int sst(int mst)
{
if(mst==-) return -;
init_lca();
int ans=INF;
for(int i=;i<e.size();i++)
{
if(!vis[i])
{
E temp=e[i];
int mx=cal_max(temp.s,temp.t);
ans=min(ans,mst-mx+temp.len);
}
}
return ans==INF ? - : ans;
} void work()
{
int mst=kruskal();
if(mst==sst(mst)) cout<<"Not Unique!"<<endl;
else cout<<mst<<endl;
} int main()
{
cin>>t;
while(t--)
{
read();
work();
}
}

POJ 1679 The Unique MST:次小生成树【倍增】的更多相关文章

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

    题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...

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

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

  3. POJ 1679 The Unique MST (次小生成树kruskal算法)

    The Unique MST 时间限制: 10 Sec  内存限制: 128 MB提交: 25  解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...

  4. poj 1679 The Unique MST (次小生成树(sec_mst)【kruskal】)

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 35999   Accepted: 13145 ...

  5. poj 1679 The Unique MST 【次小生成树】【模板】

    题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...

  6. POJ 1679 The Unique MST 【最小生成树/次小生成树模板】

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

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

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

  8. poj 1679 The Unique MST

    题目连接 http://poj.org/problem?id=1679 The Unique MST Description Given a connected undirected graph, t ...

  9. poj 1679 The Unique MST(唯一的最小生成树)

    http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submis ...

  10. poj 1679 The Unique MST (判定最小生成树是否唯一)

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

随机推荐

  1. [译]GLUT教程 - 每秒帧数

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> Frames per Second 你的程序实际上跑得多快? 有时我们 ...

  2. Android Studio 使用笔记:文件查询方法总结

    搜索单词 Windows: Ctrl + F Mac   : Cmd + F 会在当前激活的文件上查询输入的关键字,以高亮显示 跳转行 Windows: Ctrl + L Mac   : Cmd + ...

  3. 第二篇:Filebeat 安装配置

    Filebeat 简介:Filebeat 是一款轻量型日志收集工具,可转发汇总日志.文件等内容.                         其主要特点为:1. 断点续传.(如遇日志转发过程中网络 ...

  4. 【Postman】接口测试工具:在谷歌浏览器安装插件方法以及使用说明

    安装插件方法: <如何在谷歌浏览器chrome中离线安装.crx扩展程序的三种方法?> <postman chrome插件的安装与使用> 下载地址:http://www.cnp ...

  5. Linux1_Ubuntu的安装

    安装Ubuntu双系统大致有两种方式: 如果是Vmware+linux系统的话,先下载个securable.exe监测本机是否支持虚拟机的安装 1) wubi.exe安装(13.*版本不支持)2) 刻 ...

  6. 研究怎么运用xcode处理常见的调试问题

    本文转载至 http://blog.csdn.net/zhuzhihai1988/article/details/7749022 所谓磨刀不误砍柴工,这里菜鸟我在研究怎么运用xcode处理常见的调试问 ...

  7. Java 学习 day08

    01-面向对象(多态-概念) package myFirstCode; /* 多态:可以理解为事务存在的多种体现形态. 人:男人,女人 动物:猫,狗 猫 x = new 猫(); 动物 x = new ...

  8. linux集群管理

    本文以ubuntu-16.04.3-server-amd64为例,搭建服务器集群.同样是依托于虚拟机. 创建第一个节点 创建新的虚拟机参见:创建新的虚拟机,创建之后,编辑虚拟机,选择Ubuntu镜像, ...

  9. MySQL 练习 答案

    表关系 二.操作表 1.自行创建测试数据 2.查询“生物”课程比“物理”课程成绩高的所有学生的学号: 3.查询平均成绩大于60分的同学的学号和平均成绩: 4.查询所有同学的学号.姓名.选课数.总成绩: ...

  10. Django之restframework2视图三部曲

    视图三部曲 下面我来来看restframework是如何将冗余的代码一步步的进行封装. 这里主要用到的是多继承 第一步mixin类编写视图 AuthorModelSerializer: class A ...