洛谷 P1546 最短网络 Agri-Net(最小生成树)

题目链接

https://www.luogu.org/problemnew/show/P1546

说过了不复制内容了

显然是个最小生成树。

解题思路

  • prim算法
  • Kruskal算法

prim算法很直接,没什么好讲的,直接存图跑一边即可。

重点是Kruskal

难点在于存图!!

题目给的是一个邻接矩阵,而Kruskal算法是不需要建图的,所以我们需要处理一下。我们考虑哪些边可以不记录

  1. 自己和自己之间的边
  2. 重复的边(去掉a[i][j]或者a[j][i])

怎样实现2呢?当i<j或者i>j时存边即可。

附上代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 struct edge{
 5     int qidian;
 6     int zhongdian;
 7     int value;
 8 }bian[10005];
 9 int fa[105],n,ans,cnt;
10 bool cmp(edge a,edge b){
11     return a.value<b.value;
12 }
13 int find(int x){
14     if(fa[x]==x) return x;
15     return fa[x]=find(fa[x]);
16 }
17 int main()
18 {
19 cin>>n;
20 for(int i=1;i<=n;i++) fa[i]=i;
21 for(int i=1;i<=n;i++)
22 for(int j=1;j<=n;j++){    //难点:建边 
23     int x;
24     cin>>x;
25     if(i<j){
26         bian[++cnt].qidian=i;
27         bian[cnt].zhongdian=j;
28         bian[cnt].value=x;
29     }
30 }
31 sort(bian+1,bian+cnt+1,cmp);
32 for(int i=1;i<=cnt;i++){
33     int p1=bian[i].qidian,p2=bian[i].zhongdian;
34     int f1=find(p1),f2=find(p2);
35     if(f1!=f2){
36         ans+=bian[i].value;
37         fa[f1]=f2;
38     }
39 }
40 cout<<ans;
41 return 0;
42 }
AC代码

 

posted @ 2019-04-29 23:05  尹昱钦  阅读(172)  评论(0编辑  收藏  举报