回 帖 发 新 帖 刷新版面

主题:zoj 2326遇到问题寻求帮助!!(最小生成树问题)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 310
#define M 1000000
double size;
int n,m,pre[N],count;
char ch1[25],ch2[25];
char a[N][25];
typedef struct 
{
    int i,j;
    double len;
}node;
node city[M];
int cmp(const void *a,const void *b)
{
    return ((node*)a)->len-((node*)b)->len;
}
int find(int x)
{
    while(x!=pre[x])
        x=pre[x];
    return x;
}
void kruskal()
{
    double sum=0;
    int i,a,b;
    qsort(city,count,sizeof(node),cmp);
    for(i=0;i<count;i++)
    {
        a=find(city[i].i);
        b=find(city[i].j);
        if(a!=b)
        {
            sum+=city[i].len;
            pre[b]=a;
        }
    }
    if(sum>size)
        printf("Not enough cable\n");
    else
        printf("Need %.1lf miles of cable\n",sum);    
    
}

int main()
{
    int i,j;
    scanf("%lf",&size);
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        scanf("%s",a[i]);
        pre[i]=i;
    }    
    scanf("%d",&m);
    count=0;
    for(i=0;i<m;i++)
    {
        scanf("%s %s %lf",ch1,ch2,&city[count].len);
        for(j=0;j<n;j++)
        {
            if(strcmp(ch1,a[j])==0)
                city[count].i=j;
              if(strcmp(ch2,a[j])==0)
                  city[count].j=j;
        }
        count++;
    }   
    kruskal();
    return 0;
}
以上是我写的kruskal算法解这道题的代码,但一直就是错误的,纠结了一天了都;之前还做了一题与该题情形类似:都是prim算法的给过了,但是kruskal的就是过不了。我想应该是我对这个算法哪里理解有偏差了吧,望请各位能指点下在下。。先谢了  [em2]

  

这是我自一次发帖,是否分错类还是放错板块什么的希望管理员千万给过了吧,  以后一定注意。。

回复列表 (共1个回复)

沙发

int cmp(const void *a,const void *b) 这个函数写错了吧?
((node*)a)->len 的类型是 double. 比如说 (int)(1.2l - 1.3l) == 0,  (int)(1.2l - 1.0l) == 0

kruskal函数里面的那个循环有点问题,当a==b的时候,这条边是重复的,不应该计数的。


#define Bool  int
#define TRUE  1
#define FALSE 0
#define OK    1

#define TREE_MAX_HIGH 10

#define V1(edge)  (((node*)(edge)) -> i)
#define V2(edge)  (((node*)(edge)) -> j)


static inline Bool
__cmp (const void *a, const void *b)
{
  return (Bool)(((node*)a)->len > ((node*)b)->len);
}

static inline void
__cut_tree (int leaf, int root, int *tree)
{
  do {
    int parent = tree[leaf];
    tree[leaf] = root;
    leaf       = parent;
  } while (leaf != root);
}

static inline int 
__find_root (int leaf, int *tree)
{
  int high = 0;
  int root = leaf;
  for (; tree[root] != root; ++high)
    root = tree[root];

  /* 如果树的高度大于 TREE_MAX_HIGH,
   则对树进行处理,尽可能的让树不至于过高  */
  if (high > TREE_MAX_HIGH)
    __cut_tree (leaf, root, tree);
  return root;
}

static inline void
__connect (int root1, int root2, int *trees)
{
  trees[root2] = root1;
}

double 
kruskal (node *city, int *trees, int count, double maxlen)
{
  int n;
  node * edge;
  double sum = 0.0l;
  qsort (city, count, sizeof(node), __cmp);

  for (n=1, edge=city; n < count; ++edge)
    {
      int root1 = __find_root (V1(edge), trees); // 第一个顶点的根
      int root2 = __find_root (V2(edge), trees); // 第二个顶点的根
      if (root1 != root2)
       {
         n++;
         sum += edge -> len; 
         __connect (root1, root2, trees); // 把新的两个根组成1棵树 
       }
    }

  if (sum > maxlen)
    sum = -1.0l;
  return sum;
}

没有测试。

我来回复

您尚未登录,请登录后再回复。点此登录或注册