AccecptTime: 2008-12-18 12:04:07 2008-12-18 12:24:03
Language: c++
Memory: 292K 292K
Time: 0 MS
Errors: 3 RE
Algorithm: 最小生成树 Kruskal + Prim
-
- //这段代码用的是Kruskal算法,用到了并查集
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <iostream>
- using namespace std;
- typedef struct Edge{
- int x;
- int y;
- int weigh;
- }Edge;
- Edge edge[1000];
- int parent[100];
- //寻找父节点
- int FindParent(int x)
- {
- if(parent[x])
- parent[x] = FindParent(parent[x]);
- else
- return x;
- return parent[x];
- }
- //并查集合并
- void MergeSet(int x, int y)
- {
- int t1 = FindParent(x);
- int t2 = FindParent(y);
- if( t1 > t2)
- parent[t2] = t1;
- else
- parent[t1] = t2;
- }
- //用于qsort()的比较函数
- int compare(const void* a,const void* b)
- {
- return ((Edge*)a)->weigh - ((Edge*)b)->weigh;
- }
- int main()
- {
- int n, count;
- char x,y;
- int v, weigh, sum;
- cin >> n;
- while( n) {
- getchar();
- count = sum = 0;
- for( int i = 0; i < n - 1; i++) {
- cin >> x >> v;
- x = x - 'A' + 1;
- for( int j = 0; j < v; j++) {
- cin >> y >>weigh;
- y = y - 'A' + 1;
- edge[count].x = x;
- edge[count].y = y;
- edge[count++].weigh = weigh;
- }
- getchar();
- }
- qsort(edge,count,sizeof(Edge),compare);
- //对并查集进行初始化
- memset(parent,0,27 * sizeof(int));
- for(int i = 0; i < count; i++)
- //判断两个节点是否在同一个集合
- if(FindParent(edge[i].x) != FindParent(edge[i].y)) {
- sum += edge[i].weigh;
- MergeSet(edge[i].x,edge[i].y);
- }
- cout << sum << endl;
- cin >> n;
- }
- }
- #include <iostream>
- using namespace std;
- //记录集合的元素
- int in[26];
- //路径储存
- int road[26][26];
- //记录是否在集合内
- int inv[26];
- int main()
- {
- int n, v, weigh;
- int min,mink,j;
- char x, y;
- cin >> n;
- while(n) {
- int sum = 0;
- for( int i = 0; i < 26; i++)
- for( int j = 0; j < 26; j++)
- road[i][j] = 0;
- memset(inv,0,26 * sizeof(int));
- for( int i = 0; i < n - 1; i++) {
- cin >> x >> v;
- x -= 'A';
- for( int j = 0; j < v; j++) {
- cin >> y >> weigh;
- y -= 'A';
- road[x][y] = road[y][x] = weigh;
- }
- }
- in[0] = 0;
- inv[0] = 1;
- for( int i = 1; i < n; i++) {
- min = 99999999;
- for(j = 0; j < i; j++)
- for( int k = 0; k < n; k++)
- // 先判断节点是否已经加入,再判断路径是否存在,再判断路径是否最小
- if(!inv[k] && road[(in[j])][k] && road[(in[j])][k] < min) {
- min = road[in[j]][k];
- mink = k;
- }
- //将mink点加入集合,并标记
- in[j] = mink;
- inv[mink] = 1;
- sum += min;
- }
- cout << sum << endl;
- cin >> n;
- }
- }
这道题考察的是最小生成树,我分别用Kruskal 和 Prim 解出,发现内存使用和时间都是一样,但是一向低效的Prim只用了Kruskal一半多的代码(囧..),另外这道题输入很bt(在行尾会有多余空格),导致了3 RE,下次能用cin的时候要用cin。这题写得有点慢..下次遇见的时候应该直接秒杀~~