题目描述
输入格式
输出格式
思路:感觉这题建立超级源点的方法挺巧妙的,以前没有碰到过,所以记录一下。这道题如果吧超级源点到每个矿井连边,边权为建发电站的费用,可以看出,我们需要的是最小的边权和,这就成了最小生成树的模型,n只有300,跑一边prim就行了。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define ll long long int using namespace std; const int INF=0x3f3f3f3f; int n,val[305],p[305][305],ans,col[305],dis[305]; void prim(){ for(int i=1;i<=n-1;i++) dis[i]=p[n][i]; p[n][n]=INF; dis[n]=0;col[n]=1; for(register int i=1;i<=n-1;i++){ int minn=INF,k; for(int j=1;j<=n;j++) if(!col[j]&&minn>dis[j]){ minn=dis[j]; k=j; } ans+=dis[k]; col[k]=1; for(int j=1;j<=n;j++) dis[j]=min(dis[j],p[k][j]); } } int main(){ scanf("%d",&n); n++; for(int i=1;i<=n-1;i++){ scanf("%d",&p[n][i]); p[i][n]=p[n][i]; } for(int i=1;i<=n-1;i++) for(int j=1;j<=n-1;j++) scanf("%d",&p[i][j]); for(int i=1;i<=n-1;i++){ p[i][i]=INF; dis[i]=INF; } prim(); printf("%d",ans); return 0; }