2121 拆地毯
其实我非常不想做这种区间类的题目
貌似这个题不是什么区间
而是最大生成树
?!
牛逼
保留的地毯构成的图中,任意可互相到达的两点间只能有一种方式互相到达
也就是一个树
所以,我们准备用krusal算法
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#define IL inline
#define RI register int
using namespace std;
inline void inread(int &x)//快读
{
int f=1;x=0;char s=getchar();
while(s>'9' or s<'0'){if(s=='-')f=-1;s=getchar();}
while(s>='0' and s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
int fa[100008],n,m,ans,cnt,k;
struct node
{
int pre,to,w;
}edge[400008];
inline bool cmp(const node&a,const node&b)
{
return a.w>b.w;
}//边权从大到小排序.
inline int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}//路径压缩并查集
inline void kruskal()
{
sort(edge+1,edge+m+1,cmp);//排序
for(register int i=1;i<=m;i++)
{
register int u=edge[i].pre,v=edge[i].to,w=edge[i].w;
int fu=find(u),fv=find(v);
if(fu==fv) continue;
ans+=w;fa[fv]=fu;
cnt++;
if(cnt==k) break;//k边的最大生成树
}
}
int main()
{
inread(n),inread(m);inread(k);
for(register int i=1;i<=n;i++)
fa[i]=i;//并查集初始化为自己
for(register int i=1;i<=m;i++)
inread(edge[i].pre),inread(edge[i].to),inread(edge[i].w);
kruskal();//并查集操作
cout<<ans<<endl;
}
这篇博客探讨了一种区间类题目——最大生成树问题,并非传统的区间问题。作者采用Kruskal算法来解决,通过边权从大到小排序,构造保留的地毯构成的树形结构。在C++代码实现中,使用了并查集进行路径压缩,以找到包含k条边的最大生成树。
479

被折叠的 条评论
为什么被折叠?



