标签:blog -- text printf sed ons col use def
题目描述
给出一张图,求它的严格次小生成树。
思路
同秘密的牛奶运输,不再赘述。
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN=1e5+10,MAXM=3e5+10; const ll INF=1000000000000000; struct Edge { ll x,y,w; }e[MAXM]; ll fa[MAXN],tot,nxt[MAXM],to[MAXM],head[MAXN],w[MAXM]; ll f[MAXN][21],dep[MAXN]; ll g[MAXN][21][2]; bool used[MAXM]; void add_edge(ll x,ll y,ll v) { nxt[++tot]=head[x]; head[x]=tot; to[tot]=y; w[tot]=v; } bool cmp(Edge x,Edge y) { return x.w<y.w; } ll find(ll x) { return fa[x]==x?x:fa[x]=find(fa[x]); } ll cal(ll x,ll k) { ll y=f[x][k]; if(g[x][k][0]==g[y][k][0]) return max(g[x][k][1],g[y][k][1]); else if(g[x][k][0]<g[y][k][0]) return max(g[x][k][0],g[y][k][1]); else return max(g[x][k][1],g[y][k][0]); } void dfs(ll u,ll father) { dep[u]=dep[father]+1; for(ll i=0;i<=19;i++) { f[u][i+1]=f[f[u][i]][i]; g[u][i+1][0]=max(g[u][i][0],g[f[u][i]][i][0]); g[i][i+1][1]=cal(u,i); } for(ll i=head[u];i;i=nxt[i]) { ll v=to[i]; if(v==father)continue ; f[v][0]=u; g[v][0][0]=w[i]; g[v][0][1]=-INF; dfs(v,u); } } ll LCA(ll x,ll y) { if(dep[x]<dep[y])swap(x,y); for(ll i=20;i>=0;i--) { if(dep[f[x][i]]>=dep[y])x=f[x][i]; if(x==y)return x; } for(ll i=20;i>=0;i--) if(f[x][i]!=f[y][i]) { x=f[x][i]; y=f[y][i]; } return f[x][0]; } ll qmax(ll x,ll y,ll w) { ll ret=-INF; for(ll i=20;i>=0;i--) if(dep[f[x][i]]>=dep[y]) { if(w!=g[x][i][0])ret=max(ret,g[x][i][0]); else ret=max(ret,g[x][i][1]); x=f[x][i]; } return ret; } int main() { ll n,m; tot=0; scanf("%lld%lld",&n,&m); for(ll i=1;i<=m;i++) scanf("%lld%lld%lld",&e[i].x,&e[i].y,&e[i].w); sort(e+1,e+m+1,cmp); for(ll i=1;i<=n;i++) fa[i]=i; /* printf("\n"); for(int i=1;i<=m*2;i++) printf("%d %d %d\n",e[i].x,e[i].y,e[i].w);*/ ll cnt=0,sum=0; for(ll i=1;i<=m;i++) { ll fx=find(e[i].x),fy=find(e[i].y); if(fx!=fy) { fa[fx]=fy; used[i]=1; add_edge(e[i].x,e[i].y,e[i].w); add_edge(e[i].y,e[i].x,e[i].w); cnt++; sum+=e[i].w; if(cnt==n-1)break ; } } dfs(1,0); ll ans=INF; // cout<<sum<<endl; // for(int i=1;i<=n;i++) // printf("%d\n",g[i][1]); for(ll i=1;i<=m;i++) if(!used[i]) { ll lca=LCA(e[i].x,e[i].y); ll val=max(qmax(e[i].x,lca,e[i].w),qmax(e[i].y,lca,e[i].w)); // cout<<e[i].x<<‘ ‘<<e[i].y<<endl; // cout<<val<<endl; ans=min(ans,sum-val+e[i].w); } printf("%lld",ans); return 0; }
标签:blog -- text printf sed ons col use def
原文地址:https://www.cnblogs.com/fangbozhen/p/11655761.html