嗯。。。我用了两个方法一个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 ); }