hihocoder #1109 最小生成树三·堆优化的Prim算法
2016-07-22 23:13
453 查看
#include<fstream> #include<iostream> #include<string.h> #include<math.h> using namespace std; #define FOR(i,b,e) for(int i=(b);i<=(e);i++) #define FORE(i,b,e) for(int i=(b);i>=(e);i--) #define lson(x) (x<<1) #define rson(x) ((x<<1)+1) #define maxnum 100003 #define maxedge 1000003 #define INF 100003 struct edge{ int nxt; int v; int val; }e[maxedge*2]; int edgenum=0; int head[maxnum]; int heap[2*maxedge],heapnum=0; bool visit[maxnum]; int pop_heap(){ int res=heap[1]; int h=heap[heapnum]; heapnum--; int hole = 1; while(hole <= heapnum){ int index=hole<<1; if(index>heapnum) break; index = (index+1>heapnum||e[heap[index]].val<=e[heap[index+1]].val)?index:index+1; if(e[heap[index]].val<e[h].val) heap[hole]=heap[index]; else break; hole=index; } heap[hole]=h; return res; } void insert(int ed){ int i=++heapnum; while(i>1&&e[heap[i/2]].val>e[ed].val){ heap[i]=heap[i/2]; i/=2; } heap[i]=ed; } int main() { #ifdef DEBUG_ ifstream fin("G:/1.txt"); #define cin fin #endif int N,M,u,v,val; memset(e,0,sizeof(e)); memset(head,-1,sizeof(head)); memset(visit,0,sizeof(visit)); cin>>N>>M; FOR(i,0,M-1){ cin>>u>>v>>val; e[edgenum].v=v; e[edgenum].val=val; e[edgenum].nxt=head[u]; head[u]=edgenum++; e[edgenum].v=u; e[edgenum].val=val; e[edgenum].nxt=head[v]; head[v]=edgenum++; } int res = 0; int left = N - 1; visit[1] = true; for (int i = head[1]; i != -1; i = e[i].nxt) insert(i); while (heapnum!=0 && left) { int ed = pop_heap(); if (visit[e[ed].v]) continue; res += e[ed].val; left--; visit[e[ed].v] = true; for (int i = head[e[ed].v]; i != -1; i = e[i].nxt) { if (!visit[e[i].v]) insert(i); } } cout<<res<<endl; return 0; }