最小生成树 prime zoj1586
题意:在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; }