PTA---7-50 畅通工程之局部最小花费问题(最小生成树...并查集)

PTA—畅通工程之局部最小花费问题

直达链接点我!!!

思路

  • 开始一直想DFS的思路…然后发现毕竟是多条道路都要试…然后遍历起来麻烦,保存最小花费也麻烦…pass
  • 然后就是Dijkstra了…不过只能解决一个节点到其他节点的…这样其实也可以,毕竟畅通就是全部都连通了,那么就可以保存一个最小的dis数组(表示从开始这个点到其他所有点的最小花费)…但是…可能会重复花费…
  • 后来想了想,并查集可以先将已经建好的道路先并起来,然后找最小的花费(直接按花费小到大排序,用一个结构体保存输入的未建成的边),如果他俩没连通,那么这样就是最低花费了,连通起来,再去判断其他的边…

AC代码

#include <iostream>
#include <algorithm>
using namespace std;
struct way
{
    int x,y;
    int mon;
};
bool cmp(way a, way b)
{
    return a.mon < b.mon;               //从小到大
}
int a[105];
int Find(int x)
{
    if(x == a[x])
        return x;
    return a[x] = Find(a[x]);
}
bool merge(int x,int y)                 //true->已经连同 false->未连通,现在搞
{
    x = Find(x);
    y = Find(y);
    if(x != y)
    {
        a[y] = x;
        return false;
    }
    return true;
}
void ini(int n)
{
	for(int i=1;i<=n;i++)
	a[i] = i;
}
int main()
{
	
    int n,i,j,count = 1;
    scanf("%d",&n);
    way b[(n-1)*n/2];
    
    ini(n);
	int top = 0;
    for(i=0;i<n*(n-1)/2;i++)
    {
        int x,y,m,c;
        scanf("%d %d %d %d",&x,&y,&m,&c);
        if(c == 1 && !merge(x,y))
            count++;
        else
        {
            b[top].x = x;
            b[top].y = y;
            b[top].mon = m;
            top++;
        }
    }
    if(count == n)
    {
        printf("0");
        return 0;
    }
    sort(b,b+top,cmp);
    int sum = 0;
    for(i=0;i<top;i++)
    {
        int x = b[i].x;
        int y = b[i].y;
        if(!merge(x,y))                 //若未未连通
        {
            count++;
            sum += b[i].mon;
        }
        if(count == n)
            break;
    }
    printf("%d",sum);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值