bzoj 1977 [BeiJing2010组队]次小生成树 Tree [严格的次小生成树]
来源:互联网 发布:网络摄像机客户端 编辑:程序博客网 时间:2024/05/17 10:39
1977: [BeiJing2010组队]次小生成树 Tree
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 2777 Solved: 695
Description
小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足:(value(e) 表示边 e的权值) 这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。
Input
第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。
Output
包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树)
Sample Input
5 6
1 2 1
1 3 2
2 4 3
3 5 4
3 4 3
4 5 6
Sample Output
11
HINT
数据中无向图无自环; 50% 的数据N≤2 000 M≤3 000; 80% 的数据N≤50 000 M≤100 000; 100% 的数据N≤100 000 M≤300 000 ,边权值非负且不超过 10^9 。
这道题要求严格的次小MST,思路差不多,但是不能只记录max,还要记录次大值max2,更新的时候分情况讨论,具体看代码。。。
#include<iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<vector>#include<queue>#include<stack>#include<map>#include<set>#include<string>#include<iomanip>#include<ctime>#include<climits>#include<cctype>#include<algorithm>#ifdef WIN32#define AUTO "%I64d"#else#define AUTO "%lld"#endifusing namespace std;#define smax(x,tmp) x=max((x),(tmp))#define smin(x,tmp) x=min((x),(tmp))#define maxx(x1,x2,x3) max(max(x1,x2),x3)#define minn(x1,x2,x3) min(min(x1,x2),x3)typedef long long LL;const LL INF=(1ll<<60);const int maxn = 100005;const int maxm = 300005;struct Edge{ int to,next; int val;}edge[maxn<<1]; // set for the MSTint head[maxn];int maxedge;inline void addedge(int u,int v,int c){ edge[++maxedge] = (Edge) { v,head[u],c }; head[u] = maxedge; edge[++maxedge] = (Edge) { u,head[v],c }; head[v] = maxedge;}struct Road{ int u,v; int c; bool operator < (const Road t) const { return c < t.c; }}road[maxm];bool used[maxm];int n,m;LL MST;int fa[maxn];int find(int x) { return fa[x]^x? fa[x]=find(fa[x]) : x ; }inline bool union_find(int x,int y){ int t1=find(x),t2=find(y); if(t1==t2) return false; fa[t2]=t1; return true;}LL kruskal(){ int tot = 0; LL ans = 0ll; for(int i=1;i<=m;i++) { if(union_find(road[i].u,road[i].v)) tot++,ans+=road[i].c,addedge(road[i].u,road[i].v,road[i].c),used[i]=true; if(tot==n-1) break; } return ans;}#define maxd 25#define D 20int f[maxn][maxd];int dp[maxn][maxd][2];int depth[maxn];void dfs(int u,int father,int dep){ depth[u] = dep; for(int k=1;k<=D;k++) { f[u][k] = f[f[u][k-1]][k-1]; dp[u][k][0] = max(dp[u][k-1][0],dp[f[u][k-1]][k-1][0]); if(dp[u][k-1][0] == dp[f[u][k-1]][k-1][0]) dp[u][k][1] = max(dp[u][k-1][1],dp[f[u][k-1]][k-1][1]); else { dp[u][k][1] = min(dp[u][k-1][0],dp[f[u][k-1]][k-1][0]); smax(dp[u][k][1] , max(dp[u][k-1][1],dp[f[u][k-1]][k-1][1])); } } for(int i=head[u];~i;i=edge[i].next) { int v = edge[i].to; if(v==father) continue; f[v][0] = u; dp[v][0][0] = (LL)edge[i].val; // provided two number differs! dfs(v,u,dep+1); }}inline void merge(int &ans1,int &ans2,int u,int k){ int t1 = max(ans1,dp[u][k][0]) , t2; if(ans1 == dp[u][k][0]) t2 = max(ans2,dp[u][k][1]); else { t2 = min(ans1,dp[u][k][0]); smax(t2,max(ans2,dp[u][k][1])); } ans1 = t1; ans2 = t2;}pair <int,int> query(int u,int v){ int ans1 = 0; int ans2 = 0; if(depth[u]<depth[v]) swap(u,v); for(int k=D;k>=0;k--) if(depth[f[u][k]]>=depth[v]) { merge(ans1,ans2,u,k); u = f[u][k]; } if(u==v) return make_pair(ans1,ans2); for(int k=D;k>=0;k--) if(f[u][k] ^ f[v][k]) { merge(ans1,ans2,u,k); u=f[u][k]; merge(ans1,ans2,v,k); v=f[v][k]; } merge(ans1,ans2,u,0); merge(ans1,ans2,v,0); return make_pair(ans1,ans2);}void init(){ scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); maxedge=-1; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].c); sort(road+1,road+m+1); MST=kruskal(); dfs(1,-1,0);}LL work(){ LL subMST=INF; for(int i=1;i<=m;i++) if(!used[i]) { pair <int,int> tmp = query(road[i].u,road[i].v); if(road[i].c ^ tmp.first) smin(subMST,MST - tmp.first + road[i].c); else smin(subMST,MST - tmp.second + road[i].c); } return subMST;}int main(){ #ifndef ONLINE_JUDGE freopen("unique.in","r",stdin); freopen("unique.out","w",stdout); #endif init(); printf(AUTO,work()); return 0;}
0 0
- bzoj 1977 [BeiJing2010组队]次小生成树 Tree [严格的次小生成树]
- 【BZOJ 1977】 [BeiJing2010组队]次小生成树 Tree
- BZOJ 1977: [BeiJing2010组队]次小生成树 Tree
- bzoj 1977: [BeiJing2010组队]次小生成树 Tree
- 【BZOJ 1977】[BeiJing2010组队]次小生成树 Tree
- bzoj 1977: [BeiJing2010组队]次小生成树 Tree
- BZOJ 1977([BeiJing2010组队]次小生成树 Tree-LCA的位运算)
- bzoj 1977: [BeiJing2010组队]次小生成树
- 1977: [BeiJing2010组队]次小生成树 Tree kruskal+倍增
- 1977: [BeiJing2010组队]次小生成树 Tree
- bzoj 1977: [BeiJing2010组队]次小生成树 Tree 最小生成树+倍增
- BZOJ - 1977 [BeiJing2010组队]次小生成树 Tree Kruskal演算法+最近公共祖先
- 【BZOJ】1977 [BeiJing2010组队]次小生成树 Tree kruskal+LCA
- 【BZOJ】【P1977】【Beijing2010组队】【次小生成树】【题解】
- bzoj1977: [BeiJing2010组队]次小生成树 Tree
- bzoj1977: [BeiJing2010组队]次小生成树 Tree
- BZOJ1977: [BeiJing2010组队]次小生成树 Tree
- bzoj1977 [BeiJing2010组队]次小生成树 Tree
- Android:EditText动态输入监听TextWatcher
- FFMPEG结构体分析:AVFormatContext
- C++拷贝构造函数、赋值运算符重载函数使用总结
- 我是如何利用一个只有500人的QQ通过人性的弱点来变现的
- day8-9(二)
- bzoj 1977 [BeiJing2010组队]次小生成树 Tree [严格的次小生成树]
- opt/buildroot-gcc342/bin/mipsel-linux-gcc: Command not found解决办法
- 文件操作
- CoreData—使用进阶
- 域名获取IP
- 浅谈HTTP中Get与Post的区别
- 前端模块管理器简介(bower-browserify)
- (UIL)使用3之Android Universal Image Loader 源码分析
- 设置图片的渐变色