社区讨论
为什么会MLE,求大佬调
P4180[BJWC2010] 严格次小生成树参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lyzt91g7
- 此快照首次捕获于
- 2024/07/24 20:18 2 年前
- 此快照最后确认于
- 2024/07/24 20:26 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define ll int
long long read(){
long long x=0,sgn=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')sgn=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=(x<<3)+(x<<1)+(ch&15);ch=getchar();}
return x*sgn;
}
const int N=100010,M=3*1e5+10;
const int INF=0x3f3f3f3f;
struct node{
ll u,v,w;
}a[M*2];
struct Edge{
ll to,nxt,w;
}edge[M*2];
ll cnt,n,m,tmp,sum;
ll head[N],fa[N];
ll f[N][35],g[N][35],h[N][35],dep[N];
bool vis[M];
bool cmp(node a,node b){
return a.w<b.w;
}
void add(ll u,ll v,ll w) {
edge[++cnt].to=v; edge[cnt].w=w; edge[cnt].nxt=head[u]; head[u]=cnt;
}
void dfs(ll u,ll fa,ll w){
dep[u]=dep[fa]+1;
f[u][0]=fa;
g[u][0]=w;
h[u][0]=-INF;
for(int i=1;i<=20;i++){
f[u][i]=f[f[u][i-1]][i-1];
g[u][i]=max(g[f[u][i-1]][i-1],g[u][i-1]);
h[u][i]=max(h[f[u][i-1]][i-1],h[u][i-1]);
if(g[u][i-1]>g[f[u][i-1]][i-1]) h[u][i]=max(g[f[u][i-1]][i-1],h[u][i]);
else if(g[u][i-1]<g[f[u][i-1]][i-1]) h[u][i]=max(g[u][i-1],h[u][i]);
}
for(int i=head[u];i;i=edge[i].nxt){
if(edge[i].to==fa) continue;
dfs(edge[i].to,u,edge[i].w);
}
}
ll LCA(ll x,ll y){
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;i--){
if(dep[f[x][i]>dep[y]]) x=f[x][i];
}
if(x==y) return x;
for(int i=20;i>=0;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void Kruskal(){
sort(a,a+m,cmp);
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=0;i<m;i++){
int u=a[i].u,v=a[i].v,w=a[i].w;
u=find(u); v=find(v);
if(u!=v){
vis[i]=1;
tmp++;
fa[u]=v;
sum+=a[i].w;
add(i,v,w);
add(v,u,w);
}
if(tmp==n-1) break;
}
dfs(1,0,0);
}
ll qmax(ll u,ll v,ll maxx) {
ll ans=-INF;
for (int i=18;i>=0;i--) {
if (dep[f[u][i]]>=dep[v]) {
if (maxx!=g[u][i])ans=max(ans,g[u][i]);
else ans=max(ans,h[u][i]);
u=f[u][i];
}
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v>>a[i].w;
}
Kruskal();
ll ans=INF;
// cout<<ans;
for(int i=1;i<=m;i++){
if(vis[i]) continue;
ll lca=LCA(a[i].u,a[i].v);
ll max_u=qmax(a[i].u,lca,a[i].w);
ll max_v=qmax(a[i].v,lca,a[i].w);
ans=min(ans,sum-max(max_u,max_v)+a[i].w);
}
cout<<ans;
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...