poj 3925 枚举+prime

/*
因为15很小可以暴力枚举然后用最小生成树的prim来计算
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define N  40
#define inf 0x3fffffff
int a[N],f[N],en[N];
int ma[N][N],n,m;
double dd;
void prime(){
   int i,j,vv[N],dis[N],sum,total;
   double rato;
   for(i=1;i<=m;i++)
    dis[i]=inf;
  sum=a[f[1]];
  //printf("%d ",f[1]);
   for(i=2;i<=m;i++) {
     //   printf("%d ",f[i]);
     if(ma[f[1]][f[i]]!=inf)
   dis[f[i]]=ma[f[1]][f[i]];
     sum+=a[f[i]];
   }
   //printf("\n");
   total=0;
    memset(vv,0,sizeof(vv));
    vv[f[1]]=1;
   for(i=1;i<=m-1;i++) {
    int minn=inf,index;
    for(j=1;j<=m;j++)
        if(!vv[f[j]]&&minn>dis[f[j]]) {
            minn=dis[f[j]];
            index=f[j];
        }
   //printf("%d\n",minn);
        total+=minn;
        vv[index]=1;
        for(j=1;j<=m;j++)
            if(!vv[f[j]]&&dis[f[j]]>ma[index][f[j]])
                dis[f[j]]=ma[index][f[j]];
   }
  // printf("%d %d\n",total,sum);
  rato=1.0*total/(1.0*sum);
    if(rato<dd) {
        dd=rato;
        for(i=1;i<=m;i++)
            en[i]=f[i];
    }
    return ;
}
void dfs(int i,int cou) {
  if(cou==m) {
    prime();
  }
  for(;i<=n;i++) {
    f[cou+1]=i;
    dfs(i+1,cou+1);
  }
}
int main() {
   int i,j;
   while(scanf("%d%d",&n,&m),n||m) {
     for(i=1;i<=n;i++)
       scanf("%d",&a[i]);
     for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
        scanf("%d",&ma[i][j]);
      dd=inf;
     for(i=1;i<=n;i++) {
        f[1]=i;
        dfs(i+1,1);
     }
     for(i=1;i<=m-1;i++)
        printf("%d ",en[i]);
     printf("%d\n",en[i]);
   }
return 0;
}

posted @ 2014-09-17 14:53  HYDhyd  阅读(147)  评论(0编辑  收藏  举报