【题目链接】:click here~~
【题目大意】:已知某几条道路已经修完,求全部道路要通路的最小花费
【解题思路】:基础的Kruskal算法了,按照边的权值从小到大排序一遍,符合条件加入到生成树中
代码:
/* Author:HRW kruskal+并查集 */ #include <bits/stdc++.h> using namespace std; const int max_v=105; const int inf=0x3f3f3f3f; int u,v,n,m,a,b; int father[max_v]; int find(int x){ if(x==father[x]) return x; return father[x]=find(father[x]); } struct Edge{ int u,v,w; } edge[max_v*max_v]; bool cmp(Edge a,Edge b){ return a.w<=b.w; } int kruskal(int n,int m){ sort(edge,edge+m,cmp);//按照边的权值从小到大排序 int x,y; int res=0; for(int i=0; i<m; i++){ x=edge[i].u; y=edge[i].v; x=find(x);//判断是否属于同一连通分量 y=find(y); if(x!=y) { father[y]=x; res+=edge[i].w; } } return res; } void init(){ for(int i=1; i<=n; i++) father[i]=i; } int main() { while(scanf("%d",&n)!=EOF){ int aa; int p=0; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++){ scanf("%d",&aa); if(i>=j) continue;//!注意 edge[p].u=i; edge[p].v=j; edge[p].w=aa; p++; } init(); scanf("%d",&m); while(m--){ scanf("%d%d",&a,&b); a=find(a); b=find(b); father[b]=a; } printf("%d\n",kruskal(n,p)); } return 0; }
时间: 2024-11-06 07:58:49