prim
典型题。碰到这种情况,只要建一个虚拟节点,和其他的点连边,按题目给权值即可
代码中把n+1当成虚拟节点
懒得写kruskal就用prim了
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,ans,a[303][303],d[303]; bool vis[303]; int main(){ memset(d,127,sizeof(d)); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i][n+1]),a[n+1][i]=a[i][n+1]; for(int i=1;i<=n;++i) for(int j=1;j<=n;++j){ scanf("%d",&a[i][j]); if(a[i][j]==0) a[i][j]=d[0]; //改成极大值 } a[n+1][n+1]=0; d[1]=0; for(int i=1;i<=n+1;++i){ //普通的prim int u=0; for(int j=1;j<=n+1;++j) if(d[j]<d[u]&&!vis[j]) u=j; vis[u]=1; ans+=d[u]; for(int j=1;j<=n+1;++j) if(a[u][j]<d[j]&&!vis[j]) d[j]=a[u][j]; } printf("%d",ans); return 0; }