思路很简单,用kruskal算法生成最小生成森林。kruskal用并查集实现。用堆优化一下才能过。
#include
<
stdio.h
>
// disjointset
int rank[ 1001 ], set [ 1001 ];
void Makeset( int x)
... {
set[x]=x;
rank[x]=0;
}
int Find( int x)
... {
if(set[x]!=x)
set[x]=Find(set[x]);
return set[x];
}
void Link( int x, int y)
... {
if(rank[x]>rank[y])
set[y]=x;
else...{
set[x]=y;
if(rank[x]==rank[y]) rank[y]++;
}
}
void Union( int x, int y)
... {
Link(Find(x),Find(y));
}
// disjointset end
typedef struct e
... {
int a,b,w;
} Edge;
Edge E[ 10001 ];
// MinHeap
int heapsize;
void heapify( int i)
... {
int l=i<<1;
int r=(i<<1) + 1;
int smallest;
if(l<heapsize && E[l].w<E[i].w) smallest=l;
else smallest=i;
if(r<heapsize && E[r].w<E[smallest].w) smallest=r;
if(smallest!=i) ...{
Edge tmp;
tmp=E[i];
E[i]=E[smallest];
E[smallest]=tmp;
heapify(smallest);
}
}
void Build( void )
... {
int i;
for(i=heapsize>>1;i>0;i--) heapify(i);
}
Edge Extract( void )
... {
Edge t;
t=E[1];
E[1]=E[heapsize];
heapsize--;
heapify(1);
return t;
}
// min heap end
int n,m,k;
int main( void )
... {
int i;
long cost=0;
Edge tmp;
FILE *fin=stdin;
fscanf(fin,"%d %d %d ",&n,&m,&k);
heapsize=m;
for(i=1;i<=m;i++)
fscanf(fin,"%d %d %d",&E[i].a,&E[i].b,&E[i].w);
Build();
for(i=1;i<=n;i++) Makeset(i);
for(i=n;i>k && heapsize;)...{
tmp=Extract();
if(Find(tmp.a)!=Find(tmp.b))...{
Union(tmp.a,tmp.b);
cost+=tmp.w;
i--;
}else continue;
}
if (i>k) printf("No Answer ");
else printf("%d ",cost);
return 0;
}
// disjointset
int rank[ 1001 ], set [ 1001 ];
void Makeset( int x)
... {
set[x]=x;
rank[x]=0;
}
int Find( int x)
... {
if(set[x]!=x)
set[x]=Find(set[x]);
return set[x];
}
void Link( int x, int y)
... {
if(rank[x]>rank[y])
set[y]=x;
else...{
set[x]=y;
if(rank[x]==rank[y]) rank[y]++;
}
}
void Union( int x, int y)
... {
Link(Find(x),Find(y));
}
// disjointset end
typedef struct e
... {
int a,b,w;
} Edge;
Edge E[ 10001 ];
// MinHeap
int heapsize;
void heapify( int i)
... {
int l=i<<1;
int r=(i<<1) + 1;
int smallest;
if(l<heapsize && E[l].w<E[i].w) smallest=l;
else smallest=i;
if(r<heapsize && E[r].w<E[smallest].w) smallest=r;
if(smallest!=i) ...{
Edge tmp;
tmp=E[i];
E[i]=E[smallest];
E[smallest]=tmp;
heapify(smallest);
}
}
void Build( void )
... {
int i;
for(i=heapsize>>1;i>0;i--) heapify(i);
}
Edge Extract( void )
... {
Edge t;
t=E[1];
E[1]=E[heapsize];
heapsize--;
heapify(1);
return t;
}
// min heap end
int n,m,k;
int main( void )
... {
int i;
long cost=0;
Edge tmp;
FILE *fin=stdin;
fscanf(fin,"%d %d %d ",&n,&m,&k);
heapsize=m;
for(i=1;i<=m;i++)
fscanf(fin,"%d %d %d",&E[i].a,&E[i].b,&E[i].w);
Build();
for(i=1;i<=n;i++) Makeset(i);
for(i=n;i>k && heapsize;)...{
tmp=Extract();
if(Find(tmp.a)!=Find(tmp.b))...{
Union(tmp.a,tmp.b);
cost+=tmp.w;
i--;
}else continue;
}
if (i>k) printf("No Answer ");
else printf("%d ",cost);
return 0;
}