upc 兔 最小生成树


时间限制: 1 Sec 内存限制: 128 MB
[提交] [状态]
题目描述
小粉兔用集训队的奖金买下了一片地。

这片地上有 n 个房子,有些房子之间有道路,有些房子之间则是杂草。

她可以花费一定的代价拆毁一条道路,或是啃光一片草使得两个房子间可以通行(大雾)。

她喜欢生成树,所以她要让所有道路形成一棵生成树。

求最小花费。
输入
第一行一个数,n。

接下来 n 行,每行 n 个数,代表 ai,j。如果为正数,说明它们之间没有道路,需要 ai,j的花费来修建;如果为负数,说明它们之间有道路,需要 −ai,j的花费来拆毁。
输出
一行一个数,代表最小花费。
样例输入 Copy
3
0 1 -3
1 0 5
-3 5 0
样例输出 Copy
1
提示
对于 100% 的数据,5≤n≤1000,1≤|ai,j(i≠j)|≤1000,保证所有 ai,i=0且 ai,j=aj,i 。

题意就是让你在给定条件下,生成一棵树,可以在某些点之间建边,也可以删给定的边。
先不考虑建边,先考虑已经有的边,这些已经有的边,本着能不删就不删的原则 ( 这是显然的,因为删去的话可能需要重新建一条边 ) ,从大到小枚举已经有的边,能加入并查集合并的就合并,如果当前边连接的两个点已经在同一个集合当中,这个时候,因为树的结构的限制,一定需要删除这条边,而且我们是从大到小枚举的,所以删除边的代价是最小的。
至此,我们能留下的原有的边是最多的,现在需要做的就是补充完树的结构,对于可以建的边做一遍最小生成树即可。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
using namespace std;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值