这是我第三遍做这个题,这次用了二叉堆,速度可以进GCC的第一页。
C语言提交的选项对ANSI C支持的不是很好。
/*
* HDU-1233 还是畅道工程
* mike-w
* 2011-8-17
* --------------------
* 二叉堆实现PRIM
*/
#include<stdio.h>
#include<Stdlib.h>
#include<string.h>
#define MAXN 200
#define HEAP_SIZE 10000
#define INF 0Xffff
int heap[HEAP_SIZE][2]; /* heap[][0]-> distance; heap[][1]-> corresponding node */
int swap(int* e1,int* e2)
{
int t[2];
t[0]=e1[0];
t[1]=e1[1];
e1[0]=e2[0];
e1[1]=e2[1];
e2[0]=t[0];
e2[1]=t[1];
return 0;
}
int insert(int* e)
{
int n=++**heap;
heap[n][0]=e[0];
heap[n][1]=e[1];
while(n>1&&heap[n][0]<heap[n/2][0])
swap(heap[n],heap[n/2]),n/=2;
return 0;
}
int extract(int* ptr)
{
if(!**heap)
return -1;
ptr[0]=heap[1][0];
ptr[1]=heap[1][1];
swap(heap[1],heap[**heap]);
--**heap;
int n=1;
int t1;
while((t1=n<<1)<=**heap)
if(t1+1<=**heap && heap[t1+1][0]<heap[t1][0] && heap[t1+1][0]<heap[n][0])
swap(heap[t1+1],heap[n]),n=t1+1;
else if(heap[t1][0]<heap[n][0])
swap(heap[t1],heap[n]),n=t1;
else
break;
return 0;
}
/*
* 上面有不少指针,但愿不要出错
*/
int main(void)
{
int road[MAXN][MAXN];
int in[MAXN];
int N,line;
int i,j,t1,t2,t3;
long len;
int p1[2],p2[2];
#ifndef ONLINE_JUDGE
freopen("1233.in","r",stdin);
#endif
while(scanf("%d",&N),N)
{
memset(road,0,sizeof(road));
memset(in,0,sizeof(in));
memset(heap,0,sizeof(heap));
len=0;
line=N*(N-1)/2;
while(line-->0)
scanf("%d%d%d",&t1,&t2,&t3),road[t1][t2]=road[t2][t1]=t3;
p1[0]=0; /* initialize */
p1[1]=1;
insert(p1);
for(i=1;i<=N;i++)
{
while(extract(p1),in[t1=p1[1]])
;
len+=(long)p1[0];
in[t1]=1;
for(j=1;j<=N;j++)
if(!in[j]&&road[t1][j])
{
p2[0]=road[t1][j];
p2[1]=j;
insert(p2);
}
}
printf("%ld\n",len);
}
return 0;
}