/* 最小木問題に対するクラスカル法のプログラム例 */ #include #include #include #define N 1000 /* 節点数の上限 */ #define M 5000 /* 枝数の上限 */ #define ZERO 0.0001 /* 丸め誤差の許容値 */ #define TCLTKMODE /* TCLTK */ struct edge /* 構造体edgeの定義 */ { float d; /* 枝長 */ int end1, end2; /* 両端点 */ }; struct set /* 構造体setの定義 */ { int size[N]; int root[N]; int parent[N]; }; /* 関数の宣言 */ void kruskal(struct edge *E, struct edge *T, int n, int m); void quicksort(int i, int j, struct edge *A); int partition(int i, int j, float a, struct edge *A); int pivot(int i, int j, struct edge *A); void swap(int i, int j, struct edge *A); void treemerge(int i, int k, struct set *S); int treefind(int j, struct set *S); void printorg(char *s, ...){ #ifndef TCLTKMODE va_list ap; va_start(ap, s); vprintf(s, ap); va_end(ap); #endif } void printtcltk(char *s, ...){ #ifdef TCLTKMODE va_list ap; va_start(ap, s); vprintf(s, ap); va_end(ap); #endif } int main() /* 最小木のアルゴリズムのテストプログラム */ { struct edge E[M], T[N-1]; /* 枝集合E, 最小木T */ int i, k, n, m, width; /*FILE *file;*/ FILE *file = stdin; /*file=fopen("edgedata", "r");*/ { #ifdef TCLTKMODE fscanf(file, "%d", &width); #endif fscanf(file, "%d", &n); fscanf(file, "%d", &m); } for(i=0; i=aを満たす */ { int l, r, k; l=i; r=j; while(A[l].d < a-ZERO) l=l+1; while(A[r].d+ZERO >= a) r=r-1; while(l<=r) { swap(l, r, A); l=l+1; r=r-1; while(A[l].d < a-ZERO) l=l+1; while(A[r].d+ZERO >= a) r=r-1; } k=l; return(k); } int pivot(int i, int j, struct edge *A) /* A[i],...,A[j]から軸要素A[pv]を選びpvを出力 */ /* A[pv]はA[i]と最初に異なるA[k]の大きい方;すべて同じならpv=-1 */ { int pv, k; k=i+1; while(fabs(A[i].d-A[k].d)<=ZERO && k<=j) k=k+1; if(k>j) pv=-1; else if(A[i].d >= A[k].d) pv=i; else pv=k; return(pv); } void swap(int i, int j, struct edge *A) /* 構造体A[i]とA[j]の交換 */ { struct edge temp; temp=A[i]; A[i]=A[j]; A[j]=temp; return; } void treemerge(int i, int k, struct set *S) /* 集合iとkの2つの木の併合 */ { int j, large, small; if(S->size[i] <= S->size[k]) {small=i; large=k;} else {small=k; large=i;} j=S->root[small]; if(S->size[small] == 0) return; S->parent[j] = S->root[large]; S->size[large] = S->size[large]+S->size[small]; S->size[small] = 0; S->root[small] = -1; return; } int treefind(int j, struct set *S) /* jを要素とする集合iの出力と路の圧縮 */ { int i, k, temp; k=j; while(k>=0) k = S->parent[k]; i = -k-1; k=j; while(k>=0) { temp = S->parent[k]; if(temp>=0) S->parent[k] = S->root[i]; k=temp; } return(i); }