嗯。。。我用了两个方法一个kruskal,一个prim,前者,运行超时,20分,不知道怎么优化了。难道还要让我在快排的时候,用插入排序优化吗?后一个嗯。。运行错误45分。。也不知道为什么。。我查到的答案都是只有代码,没有思路,那我就来简述下思路吧。就是,最小生成树的思想,一直选择最小的边进入树中,保证天数能够最小。算法中每次循环里面都要更新天数,遇到大的就更新。然后在,最后一个结点进入树中的时候,就跳出算法。如果是kruskal算法,就是第一个结点的树根和最后一个结点的树根相同就退出,如果是prim算法,就是在最后一个结点Visite[最后一个结点] == true 时退出。大概是这样吧。最后新年快乐。我把两段代码贴出来,如果有人能告诉我怎么做就好了。
1.Prim
#include <stdio.h>
#include <malloc.h>
#define true 1
#define false 0
#define INFINITY 1000000
#define MaxVertexNum 100000
#define MaxArcNum 200000
int Visite[MaxVertexNum];
struct ArcStruct {
int v1, v2, dist;
};
struct GraphStruct {//创建一个最简单的无向图
int vexnum, arcnum;
int dist[MaxArcNum];
};
struct MinHeapStruct {
int size;
struct ArcStruct a[MaxArcNum];
};
typedef struct GraphStruct* Graph;
typedef struct MinHeapStruct* MinHeap;
typedef struct ArcStruct* Edge;
Graph createGraph();
void initializeGraph( Graph G );
int prim( Graph G, int u );
void swap( int *p1, int *p2 );
int computeNum( int a );
void assignEdge( Edge e, int v1, int v2, int dist );
Edge deleteMinHeap( MinHeap h );
void insertMinHeap( MinHeap h, Edge e );
void swapHeapNode ( Edge e1, Edge e2 );
void assignHeapNode( Edge e1, Edge e2 );
int main( void ) {
Graph G = createGraph();
int i = 0;
int V1, V2;
int dist;
int num = 0;
int mindist = 0;
for( i = 0; i < G->arcnum; i++ ) {
scanf("%d %d %d", &V1, &V2, &dist);
if( V1 < V2 ) {
swap( &V1, &V2 );
}
num = computeNum( V1-1 ) + V2-1;
G->dist[num] = dist;
}
mindist = prim( G, 0 );
printf("%d", mindist);
return 0;
}
Graph createGraph() {
Graph G = ( Graph )malloc( sizeof( struct GraphStruct ) );
initializeGraph( G );
return G;
}
void initializeGraph( Graph G ) {
int i = 0;
int n = 0;
scanf("%d %d", &G->vexnum, &G->arcnum);
n = computeNum( G->vexnum );
for( i = 0; i < n; i++ ) {
G->dist[i] = INFINITY;
}
for( i = 0; i < G->vexnum; i++ ) {
Visite[i] = false;//好像这里也可以提出来一个函数
}
}
int prim( Graph G, int u ) {
MinHeap h = ( MinHeap )malloc( sizeof(struct MinHeapStruct) );
h->size = 0;
h->a[0].dist = -INFINITY;
Visite[u] = true;
int mindist = -1;
Edge e = ( Edge )malloc( sizeof(struct ArcStruct) );
//make all edges of u into h
int num, i;
num = computeNum( u );
for( i = 0; i < u; i++ ) {
if( G->dist[num] != INFINITY ) {
assignEdge( e, u, i, G->dist[num] );
insertMinHeap( h, e );
}
num++;
}
for( i = u+1; i < G->vexnum; i++ ) {
num = computeNum( i ) + u;
if( G->dist[num] != INFINITY ) {
assignEdge( e, u, i, G->dist[num] );
insertMinHeap( h, e );
}
}
//next: MinHeap brings minest dist out, until empty.
while( h->size != 0 ) {// deleteHeap only returns one element, so union what need
e = deleteMinHeap( h );
if( !Visite[e->v2] ) {
//make all edges of e->v2 into h
u = e->v2;
Visite[u] = true;
if( mindist < e->dist ) { mindist = e->dist; }
if( Visite[G->vexnum-1] ) { break; }
num = computeNum( u );
for( i = 0; i < u; i++ ) {
if( G->dist[num] != INFINITY && !Visite[i] ) {
assignEdge( e, u, i, G->dist[num] );
insertMinHeap( h, e );
}
num++;
}
for( i = u+1; i < G->vexnum; i++ ) {
num = computeNum( i ) + u;
if( G->dist[num] != INFINITY && !Visite[i] ) {
assignEdge( e, u, i, G->dist[num] );
insertMinHeap( h, e );
}
}
}
}
return mindist;
}
void assignEdge( Edge e, int v1, int v2, int dist ) {
e->v1 = v1;
e->v2 = v2;
e->dist = dist;
}
void insertMinHeap( MinHeap h, Edge e ) {
if( h->size == 0 ) {
assignHeapNode( &(h->a[++h->size]), e );
return;
}
h->size++;
int parent, child = h->size;
assignHeapNode( &(h->a[child]), e );
for( parent = h->size/2; parent >= 1; parent = child/2 ) {
if( h->a[parent].dist <= h->a[child].dist ) { break; }
swapHeapNode( &h->a[parent], &h->a[child] );
child = parent;
}
}
Edge deleteMinHeap( MinHeap h ) {
Edge e = ( Edge )malloc( sizeof(struct ArcStruct) );
assignHeapNode( e, &(h->a[1]) );
assignHeapNode( &(h->a[1]), &(h->a[h->size]) );
h->size--;
int parent, child;
for( parent = 1; parent*2 <= h->size; parent = child ) {
child = parent*2;
if( child < h->size && (h->a[child+1].dist < h->a[child].dist) ) { child++; }
if( h->a[parent].dist <= h->a[child].dist ) { break; }
swapHeapNode( &(h->a[parent]), &(h->a[child]) );
}
return e;
}
void assignHeapNode( Edge e1, Edge e2 ) {
e1->dist = e2->dist;
e1->v1 = e2->v1;
e1->v2 = e2->v2;
}
void swapHeapNode ( Edge e1, Edge e2 ) {
Edge e3 = ( Edge )malloc( sizeof( struct ArcStruct) );
assignHeapNode( e3, e2 );
assignHeapNode( e2, e1 );
assignHeapNode( e1, e3 );
}
int computeNum( int a ) {
return a*(a-1)/2;
}
void swap( int *p1, int *p2 ) {
int tmp = 0;
tmp = *p2;
*p2 = *p1;
*p1 = tmp;
}
2.Kruskal
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define MaxArcNum 20000
#define MaxVerNum 10000
struct ArcNode {
int v1, v2, dist;
};
struct GraphStruct {
int arcnum, vexnum;
struct ArcNode a[MaxArcNum];
};
typedef struct GraphStruct* Graph;
int Parent[MaxVerNum];
int Deep[MaxVerNum];
int Kruskal( Graph G );
int findPar( int v );
void uniteTree( int v1, int v2 );
void QuickSort( struct ArcNode a[], int s, int f );
int Partition( struct ArcNode a[], int s, int f );
void swap( struct ArcNode* a, struct ArcNode* b );
int RandPartition( struct ArcNode a[], int s, int f );
void text_QuickSort( struct ArcNode a[], int s, int f );
int main( void ) {
int i = 0, v1, v2, dist;
int MinDistTree = 0;
Graph G = ( Graph )malloc( sizeof(struct GraphStruct) );
scanf("%d %d", &G->vexnum, &G->arcnum);
for( i = 0; i < G->arcnum; i++ ) {
scanf("%d %d %d", &v1, &v2, &dist);
G->a[i].v1 = v1-1;
G->a[i].v2 = v2-1;
G->a[i].dist = dist;
}
MinDistTree = Kruskal( G );
printf("%d", MinDistTree);
return 0;
}
int Kruskal( Graph G ) {
int v1, v2, dist = -1, nEdge = 0;
int i = 0;
QuickSort( G->a, 0, G->arcnum-1 );//No Problem
for( i = 0; i < G->vexnum; i++ ) {
Parent[i] = i;
Deep[i] = 0;
}
for( i = 0; i < G->arcnum && nEdge < (G->vexnum)-1; i++ ) {
v1 = G->a[i].v1;
v2 = G->a[i].v2;
if( findPar(v1) != findPar(v2) ) {
uniteTree( v1, v2 );
if( G->a[i].dist > dist ) { dist = G->a[i].dist; }
nEdge++;
if( findPar( G->vexnum-1 ) == findPar( 0 ) ) {
break;
}
}
}
return dist;
}
int findPar( int v ) {
int p = Parent[v];
int lastP = v;
while( p != lastP ) {
lastP = p;
p = Parent[lastP];
}
Parent[v] = p;
return p;
}
void uniteTree( int v1, int v2 ) {
v1 = findPar( v1 );
v2 = findPar( v2 );
if( Deep[v1] < Deep[v2] ) {
Parent[v2] = v1;
}
else {
Parent[v1] = v2;
if( Deep[v1] < Deep[v2] ) { Deep[v2]++; }
}
}
void QuickSort( struct ArcNode a[], int s, int f ) {
if( s >= f ) { return; }
int m = 0;
while( f > s ) {
m = RandPartition( a, s, f );
QuickSort( a, s, m-1 );
s++;
}
}
int Partition( struct ArcNode a[], int s, int f ) {
int x = a[f].dist;
int i = s-1;
int j = s;
for( j = s; j <= f-1; j++ ) {
if( a[j].dist < x ) {
i++;
swap( &a[i], &a[j] );
}
}
i = i+1;
swap( &a[i], &a[f] );
return i;
}
void swap( struct ArcNode* a, struct ArcNode* b ) {
struct ArcNode c = *b;
(*b).dist = (*a).dist;
(*b).v1 = (*a).v1;
(*b).v2 = (*a).v2;
(*a).dist = c.dist;
(*a).v1 = c.v1;
(*a).v2 = c.v2;
}
int RandPartition( struct ArcNode a[], int s, int f ) {
int tmp = rand()%( f-s ) + s;
swap( &a[tmp], &a[f] );
return Partition( a, s, f );
}