时间:2016-04-14 21:02:17 星期四
题目编号:[2016-04-14][ZOJ][1586][QS Network]
题目大意:给定一个n个用户,每个用户之间连接需要线路和adapter,每个连接两端各需要一个adapter,把n个节连接起来至少需要多少代价唉
分析:
- 直接prim或者kruskal
- 这里的总代价=边权+两个端点的点权,存图的时候可以直接加进去,也可以后面算法的时候计算
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 1000 + 10;int g[maxn][maxn],lowc[maxn],vis[maxn],v[maxn];int prim(int n){ int ans = 0; memset(vis,0,sizeof(vis)); vis[0] = 1; for(int i = 1; i< n ; ++i) lowc[i] = g[0][i] + v[0] + v[i]; for(int i = 1 ; i < n ; ++i){ int minc = 0x3f3f3f3f; int p = -1; for(int j = 0 ; j < n ; ++j){ if(!vis[j] && minc > lowc[j]){ minc = lowc[j]; p = j; } } if(minc == 0x3f3f3f3f) return -1; ans += minc; vis[p] = 1; for(int j = 0; j < n ; ++j){ if(!vis[j] && lowc[j] > g[p][j] + v[p] + v[j]){ lowc[j] = g[p][j] + v[p] + v[j]; } } } return ans;}int main(){ int t; scanf("%d",&t); while(t--){ int n,a; scanf("%d",&n); memset(g,0x3f,sizeof(g)); for(int i = 0 ; i < n ; ++i){ scanf("%d",&v[i]); } for(int i = 0 ; i < n ; ++i){ for(int j = 0 ; j < n ; ++j){ scanf("%d",&a); g[i][j] = min(g[i][j],a); } } printf("%d\n",prim(n)); } return 0;}