链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=586
题意:有n个适配器,不同的适配器价格不同,并给出两个适配器之间如果连接所需的网线价格,要用网线使它们连通,求所需最小费用。
思路:计算建立网络的最小费用,是个最小生成树问题。注意在构造有向网时,每条边的权值为网线的价格加上网线所连接的两个适配器的价格。由于只要求最小生成树的权值而不求选择的边,所以把lowcost数组和nearvex数组合并,lowcost[i]=-1仍表示i在集合T内。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<string> #include<cmath> #include<map> using namespace std; const int INF=1000000; const int maxn=1000+5; int n; int edge[maxn][maxn]; int lowcost[maxn]; int adapter[maxn]; void init() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&adapter[i]); for(int i=0;i<n;i++) for(int j=0;j<n;j++) { scanf("%d",&edge[i][j]); if(i==j) edge[i][j]=INF; else edge[i][j]+=adapter[i]+adapter[j]; } } void prim() { int sumw=0; lowcost[0]=-1; for(int i=1;i<n;i++) lowcost[i]=edge[0][i]; for(int i=1;i<n;i++) { int v,min=INF; for(int j=0;j<n;j++) if(lowcost[j]!=-1 && lowcost[j]<min) { v=j; min=lowcost[j]; } sumw+=min; lowcost[v]=-1; for(int i=0;i<n;i++) if(lowcost[i]>edge[v][i]) lowcost[i]=edge[v][i]; } printf("%d\n",sumw); } int main() { int t; scanf("%d",&t); while(t--) { init(); prim(); } return 0; }
究竟是我抛弃了历史,还是历史遗弃了我。