标签:题意 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