2019牛客小白月赛18 H.Forsaken喜欢独一无二的树

H.Forsaken喜欢独一无二的树

链接:https://ac.nowcoder.com/acm/contest/1221/H
来源:牛客网
在这里插入图片描述在这里插入图片描述
题意:大致上是说有一个图,告知你多少点多少边每条边权值多少,要你减去一些边,使得剩余的图的最小生成树唯一,求减去的边的权值最小是多少。

思路:最小生成树不唯一的原因只可能是有多条权值相同的边,使得构造树时有多种选择,于是我们就要把边先按权值从小到大排序。然后每组权值相同的边,先进行一次遍历,若是一条边左右两点不在已经生成的树中,就把它的权值全部加到要删除的权值del中,若在就不操作,这是因为现在的树是最小的,若在树中就不会对结果有影响;然后再进行一次遍历,这一次若是边两点不在已经生成的树中,然后让利用parent数组把这两点放进最小生成树里,让del减去它的权值,因为最小生成树中的边不能剪掉,这样子就可以把所有多余的在当前情况下的权值最小的边去掉。

#include<iostream>
#include<algorithm>
using namespace std;
int parent[200010];
typedef struct 
{
	int u;
	int v;
	int w;
}graphs;
graphs gra[200010];
bool cmp(graphs a,graphs b)
{
	return a.w<b.w;
}
int findparent(int x)
{
	return x==parent[x] ? x : parent[x]=findparent(parent[x]);
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)parent[i]=i;
	for(int i=0;i<m;i++)
	{
		cin>>gra[i].u>>gra[i].v>>gra[i].w;
	}
	sort(gra,gra+m,cmp);
	long long del=0;
	for(int i=0;i<m;)
	{
		int lastmin=i,w=gra[i].w;
		while(lastmin<m&&gra[lastmin].w==w)lastmin++;
		for(int j=i;j<lastmin;j++)
		{
			int u_p,v_p;
			u_p=findparent(gra[j].u);
			v_p=findparent(gra[j].v);
			if(u_p!=v_p)del+=w;
		}
		for(int j=i;j<lastmin;j++)
		{
			int u_p,v_p;
			u_p=findparent(gra[j].u);
			v_p=findparent(gra[j].v);
			if(u_p!=v_p)
			{
				del-=w;
				parent[u_p]=v_p;
			}
		}
		i=lastmin;
	}
	cout<<del<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值