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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值