题解 LuoguP2820 【局域网】

最小生成树裸题窝才不会告诉你窝一开始做成最大生成树的最长边了

求全图边权和\(-\)图的最小生成树

\(Code:\)

#pragma GCC diagnostic error "-std=c++11"
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
template<class T>void r(T &a)
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}
int n,m,sum;
struct edge
{
    int u,v,w;
}e[10010];
struct bcj
{
    int father[110];
    void start(int n)
    {for(int i=0;i<=n;i++)father[i]=i;}
    int find(int x)
    {if(father[x]!=x)father[x]=find(father[x]);return father[x];}
    void unionn(int x,int y)
    {x=find(x);y=find(y);if(x!=y)father[y]=x;}
    bool judge(int x,int y)
    {if(find(x)==find(y))return true;return false;}
};
bool cmp(edge a,edge b)
{
    return a.w<b.w;
}
void kruskal()
{
    bcj uf;
    int cnt=0,ans=0;
    m*=2;
    sort(e+1,e+1+m,cmp);
    uf.start(n);
    for(int i=1;i<=m;i++)
    {
        if(!uf.judge(e[i].u,e[i].v))
        {
            cnt++;
            ans+=e[i].w;
            uf.unionn(e[i].u,e[i].v);
        }
        if(cnt==n-1)break;
    }
    printf("%d",sum-ans);
}
int main()
{
    r(n,m);
    for(int i=1;i<=m;i++)
    {
        r(e[i].u,e[i].v,e[i].w);
        e[i+m]=e[i];
        sum+=e[i].w;
    }
    kruskal();
    return 0;
}
上一篇:Synchronized详解(上)


下一篇:golang的一些测试技巧和工具