题目链接:poj1258 Agri-Net
这题我上个月做过,是个大水题,今天看见有人用prim+heap做的,就学习了下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#define CLR(a,b) memset((a),(b),sizeof((a)))
using namespace std; const int inf = 0x3f3f3f3f;
const int N = ;
int low[N], s[N];
int n, ans, num;
struct Edge{
int v,c;
Edge(int _v=,int _c=):v(_v),c(_c){}
bool operator < (const Edge&r)const{
return r.c < c;
}
};
vector<Edge>g[N]; int prim_heap(){
priority_queue<Edge>q;
int i, u, v, w;
Edge p;
ans = ;//最小生成树总权值
num = ;//已加入最小生成树的顶点数目
q.push(Edge(, ));
while(!q.empty() && num < n){
p = q.top(); q.pop();
u = p.v;
if(s[u]) continue;
s[u] = ;
ans += p.c;
num++;
for(i = ; i < g[u].size(); ++i){
v = g[u][i].v;
if(s[v] == ){
w = g[u][i].c;
if(w < low[v]){
low[v] = w;
q.push(Edge(v, w));
}
}
}
}
if(num < n)
return -;
return ans;
}
int main(){
int i, j, x;
while(scanf("%d", &n) == ){
for(i = ; i < n; ++i)
g[i].clear();
for(i = ; i < n; ++i)
for(j = ; j < n; ++j){
scanf("%d", &x);
g[i].push_back(Edge(j, x));
}
CLR(s, ); CLR(low, inf);
printf("%d\n",prim_heap());
}
return ;
}