码迷,mamicode.com
首页 > 编程语言 > 详细

算法训练 安慰奶牛 最小生成树+构造

时间:2017-03-17 12:16:45      阅读:220      评论:0      收藏:0      [点我收藏+]

标签:题意   clu   bit   sizeof   pre   最小生成树   space   node   cpp   

http://lx.lanqiao.cn/problem.page?gpid=T16

题意:n个点,p条边,n,p<=1e5.每个点都有权值c[i],求选择一个点出发遍历所有点后返回需要的最小代价?

容易发现 每条边都经历了两次,边(u,v) 第一次达到v时ans+=c[v],v返回u时ans+=c[u] 则构造边为:安慰两个点(u,v)的代价为 2*w+c[u]+c[v],求出MST即可

#include <bits/stdc++.h>
using namespace std;
const int inf=1e9;
const int N=2e5+20;
struct node{
	int u,v,w;
}e[N];
int n,p,c[N],d[N],vis[N],ans;
int fa[N];
bool cmp(node a,node b)
{
	return a.w<b.w;
}
int find(int x)
{
	if(fa[x]!=x)
		fa[x]=find(fa[x]);
	return fa[x];
}
void Union(int x,int y)
{
	int fx=find(x),fy=find(y);
	fa[fx]=fy;
}
//每次用最小代价把两个连通分量合成一个 
void Kruskal()
{
	for(int i=1;i<=n;i++)
		fa[i]=i;
	sort(e,e+p,cmp);
	for(int i=0;i<p;i++)
	{
		int u=e[i].u,v=e[i].v,w=e[i].w;	
		if(find(u)!=find(v))
		{
			Union(u,v);
			ans+=w;
		}
	}		
}
int main()
{
	while(cin>>n>>p)
	{
		int mn=inf;
		ans=0;
		int u,v,w;
		for(int i=1;i<=n;i++)
		{
			cin>>c[i];
			mn=min(c[i],mn);//选择slepp的地方,起点 
		}
		for(int i=0;i<p;i++)
		{
			cin>>u>>v>>w;
			e[i].u=u,e[i].v=v;
			e[i].w=2*w+c[u]+c[v];//安慰u,v两个奶牛所需要的时间 
		}
		Kruskal();
		memset(vis,0,sizeof(vis));
		cout<<ans+mn<<endl;
		 
	}
	return 0;
}

  

算法训练 安慰奶牛 最小生成树+构造

标签:题意   clu   bit   sizeof   pre   最小生成树   space   node   cpp   

原文地址:http://www.cnblogs.com/HIKARI1149/p/6565035.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!