最小生成树 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
",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
",u,v,w);
            }
        }
        Prime(n);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/max88888888/p/6078861.html