poj 3925 枚举+prime

来源:互联网 发布:微信收费群设置 知乎 编辑:程序博客网 时间:2024/05/01 12:26
/*因为15很小可以暴力枚举然后用最小生成树的prim来计算*/#include<stdio.h>#include<string.h>#include<math.h>#define N  40#define inf 0x3fffffffint 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
原创粉丝点击