题意:在n个星球,每2个星球之间的联通需要依靠一个网络适配器,每个星球喜欢的网络适配器的价钱不同,先给你一个n,然后n个数,代表第i个星球喜爱的网络适配器的价钱,然后给出一个矩阵M[i][j]代表第i个星球到第j个星球联通所需的价钱,求联通所有星球所需的最小价钱
思路:prime 每次加入一条边的时候把边2个点的权值加进去即可 (zoj崩了,题也没法交啊,不知对错,啊~~~)
代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define mem(a) memset(a,0,sizeof(a)) using namespace std; const int N=50000; struct Edge{int fr,to;int w;friend bool operator< (Edge a, Edge b){return a.w>b.w;} }; vector<Edge>Map[N]; int p[N]; void Prime(int n){int ans=0;Edge now;bool vis[N];mem(vis);priority_queue<Edge> Q;while(!Q.empty()) Q.pop();for(int i=0; i<Map[1].size(); ++i) Q.push(Map[1][i]);vis[1]=1;n--;while(n--){now=Q.top();Q.pop();if(vis[now.to])while(vis[now.to]){now=Q.top();Q.pop();}ans+=now.w;ans+=p[now.fr]+p[now.to];vis[now.to]=1;for(int i=0; i<Map[now.to].size(); ++i)if(!vis[Map[now.to][i].to]) Q.push(Map[now.to][i]);}printf("%d\n",ans); }void Add(int u,int v,int w){Edge e;e.fr=u,e.to=v,e.w=w;Map[u].push_back(e); } int main(){int t,n,u,v,w;scanf("%d",&t);while(t--){scanf("%d",&n);mem(Map),mem(p);for(int i=1; i<=n; i++) scanf("%d",p+i);for(u=1; u<=n; ++u){for(v=1; v<=n; ++v){scanf("%d",&w);if(u!=v)Add(u,v,w),Add(v,u,w);//printf("%d %d %d\n",u,v,w); }}Prime(n);}return 0; }