严格次小生成树 并查集和数的综合应用
来源:互联网 发布:JavaScript中slice 编辑:程序博客网 时间:2024/06/04 19:29
【问题描述】
小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。
正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:(value(e)表示边e的权值)
这下小C蒙了,他找到了你,希望你帮他解决这个问题。
【输入格式】
第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点x和点y之间有一条边,边的权值为z。
【输出格式】
包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)
【输入样例】
5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
【输出样例】
11
【数据范围】
数据中无向图无自环;
50% 的数据N≤2 000 M≤3 000;
80% 的数据N≤50 000 M≤100 000;
100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。
这道题就是生成一个严格次小生成树,先生成最优生成树(详见最优生成树
),再在树上进行加边和删边处理,生成严格次小生成树。
#include<iostream>#include<cstdio>#include<cstdlib>#include<vector>#include<algorithm>#include<cstring>#include<cmath>using namespace std;const int maxn=100005;struct shu{ int u,v,w;};vector<shu>g;vector<int>a[maxn],s[maxn];int n,m,fa[maxn],pa[maxn],deep[maxn]={0},dist[maxn]={0};bool usd[300005]={0};bool my(shu a,shu b){ return a.w<b.w;}void in(){ for(int i=0;i<=n;i++) pa[i]=i;}void init(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); g.push_back((shu){x,y,z}); } in(); sort(g.begin(),g.end(),my);}int find(int x){ if(pa[x]==x) return x; pa[x]=find(pa[x]); return pa[x];} bool judge(int x,int y){ return find(x)==find(y);} void Union(int x,int y){ pa[find(x)]=find(y);}long long kruscr(){ long long sum=0; for(int i=0;i<g.size();i++) { if(judge(g[i].u,g[i].v)) continue; Union(g[i].u,g[i].v); a[g[i].u].push_back(g[i].v);//生成最小生成树。 a[g[i].v].push_back(g[i].u); s[g[i].v].push_back(g[i].w); s[g[i].u].push_back(g[i].w); usd[i]=1; sum+=(long long)g[i].w; } return sum;}void dfs(int x,int y,int z){ fa[x]=y; deep[x]=z; for(int i=0;i<a[x].size();i++) { int j=a[x][i]; if(j==y) continue; dist[j]=dist[x]+s[x][i]; dfs(j,x,z+1); }}int getmax(int x,int y,int z)//查找路径上比新边小的最大边。{ int maxv=0; if(deep[x]<deep[y]) swap(x,y); while(deep[x]>deep[y]) { if(dist[x]-dist[fa[x]]<z) maxv=max(maxv,dist[x]-dist[fa[x]]); x=fa[x]; } while(x!=y) { if(dist[x]-dist[fa[x]]<z) maxv=max(maxv,dist[x]-dist[fa[x]]); if(dist[y]-dist[fa[y]]<z) maxv=max(maxv,dist[y]-dist[fa[y]]); x=fa[x]; y=fa[y]; } return maxv;}int main(){ //freopen("in.txt","r",stdin); init(); long long sum=kruscr(); dfs(1,1,1); long long ans=100000000000000ll; for(int i=0;i<g.size();i++) if(!usd[i]) { int x=g[i].u,y=g[i].v,z=g[i].w; int t=getmax(x,y,z); ans=min(ans,sum+z-t); } cout<<ans; return 0;}
1 0
- 严格次小生成树 并查集和数的综合应用
- bzoj1977 严格的次小生成树(LCA倍增)
- bzoj 1977 [BeiJing2010组队]次小生成树 Tree [严格的次小生成树]
- 【BZOJ1977】【BJOI2011】严格次小生成树
- BJOI2011 严格次小生成树
- BZOJ1977 (严格)次小生成树
- [BJOI]2010 严格次小生成树
- 【UVA10462】【好题】【次小生成树并查集算法】
- BJOI2011 严格次小生成树 解题报告
- 【结论】【非严格次小生成树】NKOJ3855 merlin
- 【C++心路历程29】严格次小生成树
- BZOJ 1977 浅谈严格次小生成树
- POJ 1679 浅谈不严格次小生成树
- [BZOJ1977]严格次小生成树-kruskal+倍增维护
- poj 1182 食物链(并查集的综合应用)
- 【bzoj1977】【严格次小生成树】倍增维护链上最大次大值
- hdu1272小希的迷宫 (并查集应用)
- hdu 1272 小希的迷宫(并查集+最小生成树+队列)
- SDWebImage的实现机制以及解决tableView卡的问题和实现图片的缓存机制
- OPENCV将左右图像合并并写成avi视频格式
- Leetcode 204. Count Primes (Easy) (cpp)
- webservice rest
- 初学 python 环境集成
- 严格次小生成树 并查集和数的综合应用
- 编码格式简介(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)
- Intellij Idea 在spring-mybatis下因不编译resources配置文件,无法启动tomcat的问题
- 防止Document目录iCloud备份NSURLIsExcludedFromBackupKey
- Leetcode 36. Valid Sudoku (Easy) (cpp)
- NODEJS mongoose 增删改查
- c#设置对象属性——反射实体设置变量
- 入门基础——Git版本控制
- nodejs下的图形处理库gm在windows环境的安装