hdu 1879 继续畅通工程

主要思路就是先把已存在的道路用并查集并起来,再将排序后的且不存在的边遍历一遍,若边的两顶点不在一个集合内,则将两顶点并起来且将费用cost加上该边的权值

另外在网上看到另一种好的思路就是将已存在的边的权值置为0,然后进直接用最小生成树算法

#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;

int p[105],n,m;

struct edge
{
    int u,v,w;
    int flag;
}ed[5000];

int get(int x)
{
    if(p[x]==x)
        return x;
    else
        return p[x]=get(p[x]);
}

void uni(int x,int y)
{
    int a,b;
    a=get(x);
    b=get(y);
    p[a]=b;
}

bool cmp(edge a, edge b) {
    return a.w < b.w;
}

int main()
{
    int i,x,y,cost;
    while(1)
    {
        scanf("%d",&n);
        if(n==0)
            break;
        cost=0;
        m=n*(n-1)/2;
        for(i=1;i<=n;i++)
            p[i]=i;
        for(i=0;i<m;i++)
            scanf("%d%d%d%d",&ed[i].u,&ed[i].v,&ed[i].w,&ed[i].flag);
        sort(ed, ed+m, cmp);
        for(i=0;i<m;i++)
        {
            if(ed[i].flag==1)
            {    
                x=ed[i].u;
                y=ed[i].v;
                if(get(x)!=get(y))
                    uni(x,y);
            }
        }
        for(i=0;i<m;i++)
        {
            if(ed[i].flag==0)
            {
                x=ed[i].u;
                y=ed[i].v;
                if(get(x)!=get(y))
                {
                    uni(x,y);
                    cost+=ed[i].w;
                }
            }
        }
        printf("%d
",cost);
    }
    return 0;
}


 

原文地址:https://www.cnblogs.com/vermouth/p/3710236.html