zoukankan      html  css  js  c++  java
  • [題解](最小生成樹)luogu_P2916安慰奶牛

    可以發現每個點經過次數恰好等於這個點的度數,所以把點權下放邊權,跑最小生成樹,原來邊權乘二在加上兩端點權,答案再加一遍起點最小點權

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=10010;
    const int maxm=100010;
    int n,m;
    ll ans;
    struct node{
        int u,v,w,nxt;
        bool operator <(const node&a)const{
            return w<a.w;
        }
    }e[maxm*2];
    int head[maxn],cnt,w[maxn];
    int fa[maxn];
    int find(int x){
        while(x!=fa[x])x=fa[x]=fa[fa[x]];return x;
    }
    void add(int u,int v,int ww){
        e[++cnt].v=v;e[cnt].u=u;e[cnt].w=ww;e[cnt].nxt=head[u];head[u]=cnt;
        e[cnt].w=(e[cnt].w*2)+w[u]+w[v];
    }
    void kruskal(){
        for(int i=1;i<=n;i++)fa[i]=i;
        sort(e+1,e+1+cnt);
        for(int i=1;i<=cnt;i++){
            int x=find(e[i].u),y=find(e[i].v),z=e[i].w;
            if(x==y)continue;
            fa[x]=y;
            ans+=z;
        }
    }
    int main(){
        scanf("%d%d",&n,&m);int minn=0x7fffffff;
        for(int i=1;i<=n;i++)scanf("%d",&w[i]),minn=min(minn,w[i]);
        for(int i=1,u,v,w;i<=m;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
    //        add(v,u,w);
        }
        kruskal();
        printf("%lld",ans+minn);
    }
  • 相关阅读:
    最短路径的三种实现方法
    c/c++小知识
    c++ char * const p问题
    C++ typedef 四个用途
    [转]c++面向对象基础
    [转]C++中引用(&)的用法和应用实例
    表情包。
    linux基础学习
    redis缓存在项目中的使用
    关于redis
  • 原文地址:https://www.cnblogs.com/superminivan/p/10795460.html
Copyright © 2011-2022 走看看