题目链接: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. jquery validate 详解

    jQuery校验官网地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 一导入js库 <script src=&qu ...

  2. mysql导出数据库提示警告在GTID模式下面

    [root@db02 tmp]# mysqldump -S /tmp/mysql.sock -A -R --triggers --master-data=2 --single-transaction ...

  3. X264使用指南

    x264是一个开源的H.264视频编码器库.是目前最好的有损视频编码器. 基本用法是 x264 [options]-o outfile infile 主页: http://www.videolan.o ...

  4. Android DIY之路 (一) 指定区域多图片合成 放大 缩小 镜像 旋转 等(转)

    惯例先看效果图 // 注意做类似这种模板功能时候 方位由后台数据提供,这里我们用假数据 4个点 或者xy 加区域来做示例 //一开始我们公司用的是透明盖住 操作图片 但发现 局限性较大.后来直接限定区 ...

  5. ADC 分辨率和精度的区别(转载)

    转自:http://hi.baidu.com/jnjypbpuhkbajmq/item/8a6b472ae86dcc69469962b7 分辨率和精度这两个,经常拿在一起说,才接触的时候经常混为一谈. ...

  6. Mysql 复制表数据(表结构相同)

    [1]Mysql 复制表数据(表结构相同) -- 方式一: create table table_name_dest as select * from table_name_src; -- 方式二: ...

  7. 由浅到深理解ROS(4)

    消息和消息类型 节点能相互传递消息,节点之间通信也是基于消息.消息类型也就是数据类型数据类型,理解消息的类型很重要,因为它决定了消息的内容.也就是说,一个话题的消息类型能告诉你该话题中每个消息携带了哪 ...

  8. EasyDSS直播服务器如何帮助用户解决OBS不能同时同步输出多路直播流到直播平台、CDN平台的限制

    最近有用户突然寻求帮助,大概的意思就是说: 他需要同步将桌面的直播同时RTMP发布到:斗鱼.熊猫TV等等多个平台,但是OBS又只能同时采集并发布推流直播到单一个平台,而且有时候在4G或者网络比较差的情 ...

  9. java拾遗2----XML解析(二) SAX解析

    XML解析之SAX解析: SAX解析器:SAXParser类同DOM一样也在javax.xml.parsers包下,此类的实例可以从 SAXParserFactory.newSAXParser() 方 ...

  10. nginx访问日志中的时间格式修改

    1.说明 默认的时间格式是:[08/Mar/2013:09:30:58 +0800],由$time_local变量表示. 我想要改成如下格式:2013-03-08 12:21:03. 2.需要修改的文 ...