最小生成树
参考:http://www.mamicode.com/info-detail-524451.html
关键点:加一个状态0,与可建码头的地区相连
思路:
(1)只有道路便是连通图:考虑加码头与不加码头两种情况
(2)道路之间是不连通的,只有加上码头才能连通,只考虑加上码头的情况
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define MAXN 10005
#define MAXM 100005
struct node{
int u,v,w;
}edge[MAXM+MAXN];
int fa[MAXN];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
void init(int n)
{
for (int i=0;i<=n;i++)
fa[i]=i;
}
int kruscal(int n)
{
int fu,fv,w,sum=0;
for (int i=0;i<n;i++)
{
fu=find(edge[i].u);
fv=find(edge[i].v);
w=edge[i].w;
if (fu!=fv||w<0){
sum+=w;
fa[fu]=fv;
}
}
return sum;
}
int route(int n,int m)
{
init(n);
sort(edge,edge+m,cmp);
int ans=kruscal(m);
return ans;
}
int main()
{
int n,m,cost,i,fu,fv,f,k,ans,ans1;
while (cin>>n>>m)
{
for (i=0;i<m;i++)
cin>>edge[i].u>>edge[i].v>>edge[i].w;
k=m;
for (i=1;i<=n;i++)
{
cin>>cost;
if (cost!=-1)
{
edge[k].u=0;
edge[k].v=i;
edge[k++].w=cost;
}
}
init(n);
for (i=0;i<m;i++)
{
fu=find(edge[i].u);
fv=find(edge[i].v);
if (fu!=fv)
fa[fu]=fv;
}
f=find(1);
for (i=2;i<=n;i++)
{
if (f!=find(i))
break;
}
if (i==n+1)
{
ans=route(n,m);
ans1=route(n,k);
if (ans>ans1)
cout<<ans1<<endl;
else cout<<ans;
continue;
}
cout<<route(n,k)<<endl;
}
return 0;
}
也可使用qsort()排序
int cmp(const void *a,const void *b)
{
return (*(node*)a).w-(*(node *)b).w;
}
qsort(edge,m,sizeof(edge[0]),cmp);