https://www.luogu.com.cn/blog/RPdreamer/p2700
上面这篇真写得很好。本篇思路同上。
这道题需要我们删边,切断敌军。
于是,答案转化为边权总和-剩下的边。
如何选取剩下的边?将所有的边按边权从大到小排序,运用并查集加边。
不能加的情况是两个敌军直接或间接连接。若加边前原有两个连通块内有敌军,则不能加;加边时,如果新连通块内有敌军,则将其祖先节点标记。
核心代码如下:
for(ll i=1;i<n;++i)
{
int fu=Find(e[i].u),fv=Find(e[i].v);
if (enemy[fu]&&enemy[fv]) continue;//不能使敌军联通
fa[fu]=fv;if (enemy[fu]) enemy[fv]=1;//标记祖先
ans-=e[i].w;
}