[BeiJing2010组队]次小生成树 Tree
生活随笔
收集整理的這篇文章主要介紹了
[BeiJing2010组队]次小生成树 Tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
https://www.lydsy.com/JudgeOnline/problem.php?id=1977
題解:次小生成樹
/* *@Author: STZG *@Language: C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int #define endl "\n" using namespace std; typedef long long ll; //typedef __int128 lll; const int N=300000+10; const int M=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const ll INF = 0x3f3f3f3f3f3f3f; int t,n,m,k,p,l,r,u,v; ll ans,cnt,flag,temp,sum; int pre[N],dep[N],dp[N][22],maxl[N][22],maxll[N][22]; bool vis[N],used[N]; char str;struct node{int u,v,w;node(){};node(int _u,int _v,int _w):u(_u),v(_v),w(_w){}bool operator <(const node&S)const{return w<S.w;} }e[N]; vector<node>G[N]; void init(){memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++){pre[i]=i;}sum=0;ans=INF; } int find(int x){return pre[x]==x?x:pre[x]=find(pre[x]);} void marge(int x,int y){int fx=find(x);int fy=find(y);if(fx!=fy){pre[fy]=fx;} } void Kruskal(){sort(e+1,e+m+1);for(int i=1;i<=m&&cnt<n-1;i++){int fx=find(e[i].u);int fy=find(e[i].v);if(fx!=fy){cnt++;pre[fy]=fx;sum+=e[i].w;used[i]=1;G[e[i].u].push_back({e[i].u,e[i].v,e[i].w});G[e[i].v].push_back({e[i].v,e[i].u,e[i].w});}} } void dfs(int u){vis[u]=1;//cout<<G[u].size()<<endl;for(int i=0,j=G[u].size();i<j;i++){int v=G[u][i].v;if(!vis[v]){dep[v]=dep[u]+1;dp[v][0]=u;maxl[v][0]=G[u][i].w;maxll[v][0]=0;dfs(v);}} } void ST(){for(int i=0;i<21;i++){for(int j=1;j<=n;j++){dp[j][i+1]=dp[dp[j][i]][i];maxl[j][i+1]=max(maxl[j][i],maxl[dp[j][i]][i]);maxll[j][i+1]=(maxl[j][i]==maxl[dp[j][i]][i])?max(maxll[j][i],maxll[dp[j][i]][i]):min(maxl[j][i],maxl[dp[j][i]][i]);}} } int LCA(int x,int y,int w){int maxn[2]={0};if(dep[x]<dep[y]){swap(x,y);}while(dep[x]!=dep[y]){int i=log2(dep[x]-dep[y]);maxn[0]=max(maxn[0],maxl[x][i]);maxn[1]=max(maxn[1],maxll[x][i]);x=dp[x][i];}if(x==y){return maxn[0]==w?maxn[1]:maxn[0];}for(int i=log2(dep[x]);i>=0;i--){if(dp[x][i]!=dp[y][i]){maxn[0]=max(maxn[0],max(maxl[x][i],maxl[y][i]));maxn[1]=max(maxn[1],max(maxll[x][i],maxll[y][i]));x=dp[x][i];y=dp[y][i];}}if(maxl[x][0]>maxn[0]){if(maxll[x][0]>maxn[0])maxn[0]=maxl[x][0],maxn[1]=maxll[x][0];else maxn[0]=maxn[1],maxn[1]=maxl[x][0];}else if(maxl[x][0]<maxn[0]){if(maxl[x][0]>maxn[1])maxn[1]=maxl[x][0];}if(maxl[y][0]>maxn[0]){if(maxll[y][0]>maxn[0])maxn[0]=maxl[y][0],maxn[1]=maxll[y][0];else maxn[0]=maxn[1],maxn[1]=maxl[y][0];}else if(maxl[y][0]<maxn[0]){if(maxl[y][0]>maxn[1])maxn[1]=maxl[y][0];}//cout<<dp[x][0]<<endl;return maxn[0]==w?maxn[1]:maxn[0]; } void TUMST(){for(int i=1;i<=m;i++){if(!used[i]){int tu=LCA(e[i].u,e[i].v,e[i].w);//cout<<sum<<endl;ans=min(ans,sum-tu+e[i].w);}} } int main() { #ifdef DEBUGfreopen("input.in", "r", stdin);//freopen("output.out", "w", stdout); #endif//ios::sync_with_stdio(false);//cin.tie(0);//cout.tie(0);//scanf("%d",&t);//while(t--){scanf("%d%d",&n,&m);init();for(int i=1;i<=m;i++){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);}Kruskal();dfs(1);ST();TUMST();cout<<ans<<endl;//}#ifdef DEBUGprintf("Time cost : %lf s\n",(double)clock()/CLOCKS_PER_SEC); #endif//cout << "Hello world!" << endl;return 0; }?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的[BeiJing2010组队]次小生成树 Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: The Unique MST
- 下一篇: Neko Finds Grapes