社区讨论
lca死循环求助
P4180[BJWC2010] 严格次小生成树参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @lobp9cmc
- 此快照首次捕获于
- 2023/10/30 00:42 2 年前
- 此快照最后确认于
- 2023/11/04 05:23 2 年前
CPP
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int xl(int x)
{
if(x&1) return x+1;
else return x-1;
}
int n,m;
struct lsqxx
{
struct ee
{
int next;
int to;
bool can;
int val;
};
int head[maxn],cnt;
ee bb[maxn*6];
lsqxx()
{
memset(head,0,sizeof head);
cnt=0;
}
void jb(int q,int z,int v)
{
bb[++cnt].to=z;
bb[cnt].val=v;
bb[cnt].can=0;
bb[cnt].next=head[q];
head[q]=cnt;
}
};
lsqxx b1;
struct bcj
{
int fa[maxn];
void init()
{
for(int i=1;i<=n;i++)
fa[i]=i;
}
int cz(int x)
{
int r=x;
while(fa[x]!=x) x=fa[x];
return fa[r]=x;
}
bool hb(int x,int y)
{
x=cz(x),y=cz(y);
if(fa[x]==fa[y]) return 0;
fa[x]=y;
return 1;
}
};
bcj bc;
struct eb
{
int q;
int z;
int val;
int cnt;
bool can;
eb()
{
q=z=val=0;can=0;
}
eb(int _q,int _z,int _v)
{
q=_q,z=_z,val=_v;can=0;
}
friend bool operator <(eb a,eb b)
{
return a.val<b.val;
}
};
struct zxscs
{
eb ed[maxn];
int solve()
{
sort(ed+1,ed+1+n);
int ans=0;
for(int i=1;i<=m;i++)
{
eb t=ed[i];
if(bc.hb(t.q,t.z)==0)
b1.bb[t.cnt].can=1,b1.bb[t.cnt+1].can=ed[i].can=1,ans+=ed[i].val;
}
return ans;
}
};
zxscs sc;
struct spp
{
int fa[maxn],lfa[maxn],size[maxn],son[maxn];
int top[maxn],mp[maxn],sd[maxn];
void init()
{
memset(mp,0,sizeof mp);
memset(son,0,sizeof son);
}
void dfs(int x,int f,int ss)
{
fa[x]=f;size[x]=1;sd[x]=ss;
for(int i=b1.head[x];i;i=b1.bb[i].next)
{
int sx=b1.bb[i].to;
if(b1.bb[i].can&&sx!=f)
{
dfs(sx,x,ss+1);lfa[sx]=b1.bb[i].val;
size[x]=size[sx]+size[x];
if(size[sx]>size[son[x]])
son[x]=sx;
}
}
}
void dfs2(int x)
{
if(x==son[fa[x]])
top[x]=top[fa[x]],mp[top[x]]=max(mp[top[x]],lfa[x]);
else top[x]=x;
if(son[x])
dfs2(son[x]);
for(int i=b1.head[x];i;i=b1.bb[i].next)
{
int sx=b1.bb[i].to;
if(sx!=son[x]&&sx!=fa[x])
dfs2(son[x]);
}
}
int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(sd[top[x]]<sd[top[y]]) swap(x,y);
x=fa[top[x]];
}
if(sd[x]<sd[y]) swap(x,y);
return x;
}
int cz(int x,int y)
{
int t=lca(x,y);cout<<1;
int ans=0;
if(top[x]==top[t])
{
while(x!=t)
{
ans=max(ans,lfa[x]);
x=fa[x];
}
}
else
{
while(x!=top[x])
{
ans=max(ans,lfa[x]);
x=fa[x];
}
while(top[fa[x]]!=top[t])
{
ans=max(ans,max(lfa[x],mp[fa[x]]));
x=fa[top[x]];
}
while(x!=t)
{
ans=max(ans,lfa[x]);
x=fa[x];
}
}
if(top[y]==top[t])
{
while(y!=t)
{
ans=max(ans,lfa[y]);
y=fa[y];
}
}
else
{
while(y!=top[y])
{
ans=max(ans,lfa[y]);
y=fa[y];
}
while(top[fa[y]]!=top[t])
{
ans=max(ans,max(lfa[y],mp[fa[y]]));
y=fa[top[y]];
}
while(y!=t)
{
ans=max(ans,lfa[y]);
y=fa[y];
}
}
return ans;
}
};
spp sp;
int main()
{
scanf("%d%d",&n,&m);
bc.init();
sp.init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&sc.ed[i].q,&sc.ed[i].z,&sc.ed[i].val);
sc.ed[i].cnt=i*2-1;
b1.jb(sc.ed[i].q,sc.ed[i].z,sc.ed[i].val);
b1.jb(sc.ed[i].z,sc.ed[i].q,sc.ed[i].val);
}
int maxz=sc.solve();//cout<<maxz;
sp.dfs(1,1,1);
sp.dfs2(1);
int min1=INT_MAX,min2=INT_MAX;
for(int i=1;i<=m;i+=2)
{
eb w=sc.ed[i];
if(w.can==0)
{
int mq=maxz-sp.cz(w.q,w.z)+w.val;
if(mq<=min2)
min2=mq;
else if(mq<min2)
min2=min1,min1=mq;
}
}
if(min1!=maxz) printf("%d",min1);
else printf("%d",min2);
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...