题意:给你n个点 然后给你n个值 分别是每个点建立一条边的初始花费 然后再给你n*n 的矩阵 分别是点距 求最短路
解题思路:把两个点建立的一条边的初始花费也算入到这条边的权值中,从而利用Kruskal 算法排序然后求最下生成树
解题代码:
// File Name: g.cpp // Author: darkdream // Created Time: 2013年04月25日 星期四 01时11分49秒 #include<vector> #include<list> #include<map> #include<set> #include<deque> #include<stack> #include<bitset> #include<algorithm> #include<functional> #include<numeric> #include<utility> #include<sstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<ctime> int p[1000]; int c[1000]; int w[1000005]; int v[1000005]; int u[1000005]; int r[1000005]; int d[1005][1005]; using namespace std; int find(int x) { return p[x] == x? x:p[x] = find(p[x]); } int cmp(const int i , const int j) { return w[i] < w[j]; } int main(){ int t; scanf("%d",&t); while(t--) { int n ; scanf("%d",&n); for(int i =1;i <= n;i ++) scanf("%d",&c[i]); for(int i =1 ;i <= n;i ++) for(int j =1;j <= n; j ++) { scanf("%d",&d[i][j]); } int m = 0; for(int i = 2;i <= n; i ++) for(int j =1 ; j< i;j ++) { v[++m] =i ; u[m] = j; w[m] = c[i] +c[j] + d[i][j]; } for(int i = 1;i <= n;i ++) p[i] = i; for(int i = 1 ;i <= m; i ++) r[i] = i; sort(r+1,r+m+1,cmp); int ans = 0; for(int i =1;i <= m; i ++) { int e = r[i]; int x = find(v[e]); int y = find(u[e]); if(x != y) { ans += w[e]; p[x] = y; } } printf("%d\n",ans); } return 0; }