POJ 1679 The Unique MST:次小生成树【倍增】
题目链接: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:次小生成树【倍增】的更多相关文章
- POJ 1679 The Unique MST (次小生成树)
题目链接:http://poj.org/problem?id=1679 有t组数据,给你n个点,m条边,求是否存在相同权值的最小生成树(次小生成树的权值大小等于最小生成树). 先求出最小生成树的大小, ...
- POJ 1679 The Unique MST (次小生成树 判断最小生成树是否唯一)
题目链接 Description Given a connected undirected graph, tell if its minimum spanning tree is unique. De ...
- POJ 1679 The Unique MST (次小生成树kruskal算法)
The Unique MST 时间限制: 10 Sec 内存限制: 128 MB提交: 25 解决: 10[提交][状态][讨论版] 题目描述 Given a connected undirect ...
- poj 1679 The Unique MST (次小生成树(sec_mst)【kruskal】)
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 35999 Accepted: 13145 ...
- poj 1679 The Unique MST 【次小生成树】【模板】
题目:poj 1679 The Unique MST 题意:给你一颗树,让你求最小生成树和次小生成树值是否相等. 分析:这个题目关键在于求解次小生成树. 方法是,依次枚举不在最小生成树上的边,然后加入 ...
- POJ 1679 The Unique MST 【最小生成树/次小生成树模板】
The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22668 Accepted: 8038 D ...
- POJ1679 The Unique MST —— 次小生成树
题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total S ...
- poj 1679 The Unique MST
题目连接 http://poj.org/problem?id=1679 The Unique MST Description Given a connected undirected graph, t ...
- poj 1679 The Unique MST(唯一的最小生成树)
http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total Submis ...
- poj 1679 The Unique MST (判定最小生成树是否唯一)
题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS Memory Limit: 10000K Total S ...
随机推荐
- Android Studio中查看类的继承关系
查看类的继承关系的快捷键F4.在Android Studio经常使用快捷键这篇文章中.有写了.今天主要是讲一些关于这个快捷键出来的界面的一些配置.这块功能相对偏冷一些,可能非常多人都会用不到.可是关于 ...
- Downloading jQuery
Compressed and uncompressed copies of jQuery files are available. The uncompressed file is best used ...
- COM线程模型 套间概念
COM线程模型 套间概念 1) 单线程套间.线程是COM主线程,初始化COM库的进程的第一个线程.即使从其他线程访问COM组件,也不需要手工同步,COM库已经实现了同步.寓所线程里有个消息处理循环来处 ...
- vue实践---vue配合express实现请求数据mock
mock数据是前端比较常见的技术,这里介绍下vue配合express 实现请求数据mock. 第一步: 安装 express : npm install express -D 第二步: 简历需要mo ...
- Python菜鸟之路:Python基础(三)
一.编码 推荐阅读<字符编码的前世今生>:http://tgideas.qq.com/webplat/info/news_version3/804/808/811/m579/201307/ ...
- 云计算服务的三种类型(SaaS、PaaS、IaaS)
云计算可以帮助企业降低IT方面的成本和复杂性,并获得他们蓬勃发展所需的灵活性与敏捷性.但是,规划出通往云的明确路径并非易事.毕竟用户需要看透与云相关的市场大肆宣传,然后理解并分析不同种类的云计算模式的 ...
- js判断undefined类型,undefined,null, 的区别详细解析
js判断undefined类型 今天使用showModalDialog打开页面,返回值时.当打开的页面点击关闭按钮或直接点浏览器上的关闭则返回值是undefined所以自作聪明判断 var reVal ...
- ADO.NET概述
xml这类文件它是.net变成环境中优先使用的数据访问借口. ADO.NET传输的数据都是XML格式的 ADO.NET是一组用于和数据源惊醒交互的面向对象类库 数据源:通常是各种数据库,但文本.exc ...
- 有关numpy.random下的API具体含义
1.numpy.random.random(size=None) Return random floats in the half-open interval [0.0, 1.0). 返回size大小 ...
- 改善程序与设计的55个具体做法 day5
条款12:复制对象时勿忘其每一个成分 这里的复制是拷贝构造和operator= 每一个成分有几个维度: 1.每个成员变量 这个很好理解,添加新的成员时也要记得为每个新添加的成员执行合适的复制操作 2. ...