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 ...
随机推荐
- iOS ZipArchive文件解压缩
ZipArchive可以用于iOS中文件的解压缩 压缩文件的方法: //将工程中picture添加到左面111.zip压缩文件中 如果崩溃请更换压缩路径 -(void)testZipFile{ //压 ...
- iOS GCD倒计时
GCD倒计时的好处在于不用考虑是否定时器无法释放的问题,runloop的问题,还有精度更加高 使用GCD创建定时器方法 -(void)startCountDown:(NSInteger)maxTime ...
- Android学生管理系统
现在要做这么一个小的demo,可以添加.展示,并且在添加完了之后刷新列表内容. 要点: 在代码中给线性布局添加View 让控件滚动,放到ScrollView中 保存数据就是把数据保存到本地,然后恢复的 ...
- NOJ1167 丑陋数 想法题
题意 丑陋数n的意思是n的全部素数因子仅仅有2,3,5. 求出前1500个丑陋数. (第一个丑陋数是1) 思路 用一个数组维护全部的丑陋数. 一開始数组中仅仅有一个数就是1. 如今能够确定的丑陋数还有 ...
- 判断终端是ios还是安卓的一些妙用
最近遇到一个项目 要求有两个icon(就是下载地址 下载安卓的apk 和ios的安装包) 一开始的方案是 什么设备都显示这两个icon 但是后来老大说这样不好 安卓用户给他下载ios 也不行 ...
- C#获取当前时间的各种格式
C#获取当前时间的各种格式 DateTime.Now.ToShortTimeString() DateTime dt = DateTime.Now; dt.ToString();//2005 ...
- 2016/05/17 thinkphp3.2.2 分页的使用:①在Home下设置Publics文件夹或在thinkPHP下library的vender 把page.class.php 考贝进入 ②通过new 实例化方式调用 $page=new \Home\Publics\Page($total,3);
注意分页的方法有两种:一种是thinkphp3.2 自带的 另一种是之前新闻页用过的 显示效果稍有差别 显示效果: 细节问题: ①搜索页面 要加session判断 和 分页 ②修改 ...
- EasyNVR无插件H5/HLS/m3u8直播解决方案中Windows系统服务启动错误问题的修复:EasyNVR_Service 服务因 函数不正确。 服务特定错误而停止。
最近在做某地市移动公司景观直播的项目时,遇到一个问题,当我们部署EasyNVR为系统服务后,居然出现了无法启动服务的现象,表面上看,提示是系统服务启动失败,实际通过查看windows 系统日志: 查找 ...
- 九度OJ 1189:还是约瑟夫环 (约瑟夫环)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:820 解决:522 题目描述: 生成一个长度为21的数组,依次存入1到21: 建立一个长度为21的单向链表,将上述数组中的数字依次存入链表每 ...
- nginx学习之静态内容篇(五)
1.根目录和索引文件 server { root /www/data; location / { } location /images/ { } location ~ \.(mp3|mp4) { ro ...