洛谷 P1550 [USACO08OCT]Watering Hole G(最小生成树||超级源点)

题目链接:https://www.luogu.com.cn/problem/P1550

将在第i号田挖一个井,可以设一个超级源点,将超级源点到第i号点的边权看成是在第i号田挖井的代价,构成一个图,求这个图的最小生成树即为答案。

注意有300个顶点,最多会有300*300条边,数组要开够。

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=500005;
 6 int n,ans,f[N],tot;
 7 struct node{
 8     int u,v,w;
 9 }edge[N];
10 bool cmp(node a,node b){
11     return a.w<b.w;
12 }
13 int find(int x){
14     if(x!=f[x]) f[x]=find(f[x]);
15     return f[x];
16 }
17 int main(){
18     scanf("%d",&n);
19     for(int i=1;i<=n;i++){
20         int w; scanf("%d",&w);
21         edge[++tot].u=0;
22         edge[tot].v=i;
23         edge[tot].w=w;
24     }
25     for(int i=1;i<=n;i++)
26     for(int j=1;j<=n;j++){
27         int w; scanf("%d",&w);
28         if(j<=i) continue;
29         edge[++tot].u=i;
30         edge[tot].v=j;
31         edge[tot].w=w;
32     }
33     for(int i=0;i<=n;i++) f[i]=i;
34     sort(edge+1,edge+tot+1,cmp);
35     for(int i=1;i<=tot;i++){
36         int r1=find(edge[i].u);
37         int r2=find(edge[i].v);
38         if(r1!=r2){
39             f[r1]=r2;
40             ans+=edge[i].w;
41         }
42     }
43     printf("%d",ans);
44     return 0;
45 }
46 //300*300条边 
AC代码
原文地址:https://www.cnblogs.com/New-ljx/p/13817925.html