【题目来源】http://poj.org/problem?id=1287
【题目思路】最小生成树,本题估计不用优化也能过,我还是用堆优化了prim,仅仅作为练手。
【题目感想】
#define INF (~0u)>>2可以用来定义无穷大
堆中元素保存的是节点的编号
【代码】
#include <iostream>
#include <cstdlib>
#include <cstring>
#define MAXN 100
#define MAXM 10000
#define INF (~0u)>>2
using namespace std;
struct EdgeNode
{
int to,w,next;
};
EdgeNode edge[MAXM]={0};
int n,m,cnt;
int head[MAXN],dist[MAXN]={0};
void addedge(int u,int v,int w)
{
edge[++cnt].to=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
head[u]=cnt;
}
int heap[MAXN]={0},pos[MAXN]={0};
int heap_size=0;
void upHeapify(int k)
{
while (k>1)
{
if (dist[heap[k/2]] > dist[heap[k]])
{
swap(pos[heap[k/2]],pos[heap[k]]);
swap(heap[k/2],heap[k]);
k/=2;
}
else
break;
}
}
void downHeapify(int k)
{
while (k*2 <=heap_size)
{
int j;
if ( k*2==heap_size || dist[heap[k*2]]<dist[heap[k*2+1]])
j=k*2;
else
j=k*2+1;
if (dist[heap[k]]>dist[heap[j]])
{
swap(pos[heap[k]],pos[heap[j]]);
swap(heap[k],heap[j]);
k=j;
}
else
break;
}
}
void push(int node,int x)
{
dist[node]=x;
heap[++heap_size]=node;
pos[node]=heap_size;
upHeapify(heap_size);
}
int pop()
{
int ret=heap[1];
swap(pos[heap[heap_size]],pos[heap[1]]);
swap(heap[heap_size],heap[1]);
--heap_size;
downHeapify(1);
return ret;
}
int prim()
{
int mst=0;
push(1,0);
for (int i=2;i<=n;++i)
push(i,INF);
for (int i=1;i<=n;++i)
{
int t=pop();
mst+=dist[t];
pos[t]=-1;
for (int k=head[t];k!=0;k=edge[k].next)
{
int dest=edge[k].to;
if (pos[dest]!=-1 && dist[dest]>edge[k].w)
{
dist[dest]=edge[k].w;
upHeapify(pos[dest]);
downHeapify(pos[dest]);
}
}
}
return mst;
}
int main()
{
std::ios::sync_with_stdio(false);
int u,v,w;
while (cin>>n,n!=0)
{
cin>>m;
cnt=0;
for (int i=1;i<=n;++i)
head[i]=dist[i]=0;
for (int k=1;k<=m;++k)
{
cin>>u>>v>>w;
addedge(u,v,w);
addedge(v,u,w);
}
cout<<prim()<<endl;
}
return 0;
}