F. Make It Connected(krustra+)

题目链接:http://codeforces.com/contest/1095/problem/F

 题目大意:首先给你n个点,然后给你每个点的权值,再给你m条边,这些边可以选也可以不选,然后问你要使这个加边构成的图联通的最小花费。

 具体思路:我们可以先找出权值最小的点,然后别的点都向向这个点连一条边,这是当前使得图联通的最小构图的方法,然后再看一下题目给定的点加上,注意题目给定的权值不一定是最小的。(如果是用spfa算法的话,就需要建立双向边,然后用krustra的话,没有建立双向边的必要,建立起来就可以了)

AC代码:

 1 #include <iostream>
 2 #include<stdio.h>
 3 #include<string>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 # define ll long long
 8 # define LL_inf 1ll<<60
 9 const int maxn  =4e5+10;
10 struct node
11 {
12     int fr;
13     int to;
14     ll cost;
15 } q[maxn];
16 ll a[maxn];
17 int father[maxn],num;
18 int Find(int t)
19 {
20     return t==father[t]?t:father[t]=Find(father[t]);
21 }
22 bool cmp(node t1,node t2)
23 {
24     return t1.cost<t2.cost;
25 }
26 ll krustra()
27 {
28     ll sum=0;
29     for(int i=1; i<=num; i++)
30     {
31         int t1=Find(q[i].fr);
32         int t2=Find(q[i].to);
33         if(t1!=t2)
34         {
35             father[t1]=t2;
36             sum+=q[i].cost;
37         }
38     }
39     return sum;
40 }
41 int main()
42 {
43     int n,m;
44     scanf("%d %d",&n,&m);
45     ll minn=LL_inf;
46     int id=0;
47     for(int i=1; i<=n; i++)
48     {
49         father[i]=i;
50         scanf("%lld",&a[i]);
51         if(a[i]<minn)
52         {
53             minn=a[i];
54             id=i;
55         }
56     }
57     int st,ed;
58     ll co;
59     for(int i=1; i<=m; i++)
60     {
61         scanf("%d %d %lld",&st,&ed,&co);
62         co=min(a[st]+a[ed],co);
63         q[++num].fr=st;
64         q[num].to=ed;
65         q[num].cost=co;
66     }
67     for(int i=1; i<=n; i++)
68     {
69         if(i==id)
70             continue;
71         q[++num].fr=i;
72         q[num].to=id;
73         q[num].cost=a[i]+a[id];
74     }
75     sort(q+1,q+num+1,cmp);
76     ll ans=krustra();
77     printf("%lld\n",ans);
78     return 0;
79 }
80  

 

posted @ 2018-12-28 20:02  Let_Life_Stop  阅读(165)  评论(0编辑  收藏  举报