最小生成树


#include <cstdio> 
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue> 
#include <set>
using namespace std;
#define maxn 120005
#define maxm 10005

struct edge
{
    int u;int v;int cost;
}es[maxn];

bool cmp(const edge& e1,const edge& e2)
{
    return e1.cost < e2.cost;
}

int V,E,num = -1;
int par[maxm];

void init(int n)
{
    for(int i=0;i <= n;i++)
        par[i] = i;
}

int find(int x)
{
    return par[x] = par[x] == x ? x : find(par[x]);
}

void unite(int x,int y)
{
    int a = find(x),b= find(y);
    if(a != b) par[a] = b;
}

bool same(int x,int y)
{
    return find(x) == find(y);
}

int kruskal()
{
    sort(es,es+E,cmp);
    init(V);
    int res = 0;
    for(int i = 0;i < E;i++)
    {
        edge e = es[i];
        if(!same(e.u,e.v) || e.cost<0)
        {
            unite(e.u,e.v);
            res += e.cost;
        }
    }
    return res;
}


int main()
{
    scanf("%d%d",&V,&E);
    int a,b,val,c;
    for(int i = 1;i <= E;i++)
    {
        scanf("%d%d%d",&a,&b,&val);
        es[++num].u = a;es[num].v = b;es[num].cost = val;
    }
    int temp  = kruskal();
    int x;
    for (x = 2; x <= V; x++) if (find(1) != find(x)) break; 
    if(x != V+1)
    {
        for(int i = 1; i <= V;i++)
        {
            scanf("%d",&c);
            if(c == -1) continue;
            E++;
            es[++num].u = 0;es[num].v = i;es[num].cost = c;
        }
        printf("%d",kruskal());
    }else{
        for(int i = 1; i <= V;i++)
        {
            scanf("%d",&c);
            if(c == -1) continue;
            E++;
            es[++num].u = 0;es[num].v = i;es[num].cost = c;
        }
        printf("%d",min(temp,kruskal()));
    }
    return 0; 
} 


    
            
原文地址:https://www.cnblogs.com/inerbornthisway/p/8531639.html