题意为将所有点连起来,但是有些边已经帮你连好了,要求你将剩下的连起来形成最小生成树。
因为一些点已经连起来了,所以应该选用kruskal算法。虽然这道题的图是按照邻接矩阵给出的,但选用prim算法的话,实现起来反而不容易还容易出错,倒不如自己对输入进行一些加工,然后选取kruskal算法。
#include <iostream> #include <stdio.h> #include <queue> using namespace std; int input[105][105]; int N; int parent[105]; struct Edge { int s,e,w; Edge(int ss,int ee,int ww):s(ss),e(ee),w(ww){} Edge(){} bool friend operator<(Edge n1,Edge n2) { return n1.w>n2.w; } }; int findP(int x) { if(x==parent[x]) return x; else return parent[x]=findP(parent[x]); } void Union(int x,int y) { int xp=findP(x),yp=findP(y); parent[yp]=xp; } void kruskal() { int ans=0; priority_queue<Edge> Q; for(int i=1;i<=N;i++) { for(int j=i+1;j<=N;j++) { Q.push(Edge(i,j,input[i][j])); } } while(!Q.empty()) { Edge now=Q.top(); Q.pop(); if(findP(now.s)!=findP(now.e)) { ans+=now.w; Union(now.s,now.e); } } cout<<ans<<endl; } int main() { int t,a,b; while(~scanf("%d",&N)) { for(int i=1;i<=N;i++) { for(int j=1;j<=N;j++) { scanf("%d",&input[i][j]); } parent[i]=i; } scanf("%d",&t); while(t--) { scanf("%d%d",&a,&b); Union(a,b); } kruskal(); } return 0; }
来源:https://www.cnblogs.com/modengdubai/p/4748934.html